信号之函数system、sleep、nanosleep以及clock_nanosleep
本文来自个人博客:https://dunkwan.cn
文章目录
- 函数`system`
- 函数`sleep`、`nanosleep`和`clock_nanosleep`
函数system
由于system
执行的命令可能是交互式的命令,因为system
的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system
的调用者就不应接收SIGINT
和SIGQUIT
这两个终端产生的信号。
测试示例1:
system
实现版本一,为考虑忽略SIGINT
和SIGQUIT
信号。
#include "../../include/apue.h"
#include <sys/wait.h>
#include <unistd.h>int system(const char *);
static void sig_int(int);
static void sig_chld(int);int main(void)
{if(signal(SIGINT, sig_int) == SIG_ERR)err_sys("signal(SIGINT) error");if(signal(SIGCHLD, sig_chld) == SIG_ERR)err_sys("signal(SIGCHLD) error");if(system("/bin/ed") < 0)err_sys("system() error");return 0;
}int system(const char *cmdstring) /* version without signal handling */
{pid_t pid;int status;if (cmdstring == NULL)return(1); /* always a command processor with UNIX */if ((pid = fork()) < 0) {status = -1; /* probably out of processes */} else if (pid == 0) { /* child */execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);_exit(127); /* execl error */} else { /* parent */while (waitpid(pid, &status, 0) < 0) {if (errno != EINTR) {status = -1; /* error other than EINTR from waitpid() */break;}}}return(status);
}static void sig_int(int signo)
{printf("caught SIGINT\n");
}static void sig_chld(int signo)
{printf("caught SIGCHLD\n");
}
结果如下:
测试示例2:
system
函数版本2,此版本进行了所要求的信号的处理。
#include "../../include/apue.h"
#include <sys/wait.h>static void sig_int(int);
static void sig_chld(int);
int system(const char *);int main()
{if(signal(SIGINT, sig_int) == SIG_ERR)err_sys("signal(SIGINT) error");if(signal(SIGCHLD, sig_chld) == SIG_ERR)err_sys("signal(SIGCHLD) error");if(system("/bin/ed") < 0)err_sys("system() error");return 0;
}static void sig_int(int signo)
{printf("caught SIGINT\n");
}static void sig_chld(int signo)
{printf("caught SIGCHLD\n");
}int system(const char *cmdstring) /* with appropriate signal handling */
{pid_t pid;int status;struct sigaction ignore, saveintr, savequit;sigset_t chldmask, savemask;if(cmdstring == NULL)return (1);ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */sigemptyset(&ignore.sa_mask);ignore.sa_flags = 0;if(sigaction(SIGINT, &ignore, &saveintr) < 0)return (-1);if(sigaction(SIGQUIT, &ignore, &savequit) < 0)return (-1);sigemptyset(&chldmask);sigaddset(&chldmask, SIGCHLD);if(sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)return (-1);if((pid = fork()) < 0){status = -1;}else if(pid == 0){sigaction(SIGINT, &saveintr, NULL);sigaction(SIGQUIT, &savequit, NULL);sigprocmask(SIG_SETMASK, &savemask, NULL);execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);_exit(127);}else{while(waitpid(pid, &status, 0) < 0)if(errno != EINTR){status = -1;break;}}if(sigaction(SIGINT, &saveintr, NULL) < 0)return (-1);if(sigaction(SIGQUIT, &savequit, NULL) < 0)return (-1);if(sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)return (-1);return (status);
}
结果如下:
函数sleep
、nanosleep
和clock_nanosleep
sleep
函数定义如下:
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
返回值:0或未休眠完的秒数。
此函数使调用进程被挂起直到满足下面两个条件之一。
- 已经过了
seconds
所指定的墙上时钟时间。- 调用进程捕捉到一个信号并从信号处理程序返回。
以下是一个POSIX.1的sleep
函数的实现。
#include "apue.h"static void sig_alrm(int signo){/* nothing to do, just returned wakes up sigsuspend() */
} unsigned int sleep(unsigned int seconds)
{struct sigaction newact, oldact;sigset_t newmask, oldmask, suspmask;unsigned int unslept;/* set our handler, save previous information */newact.sa_handler = sig_alrm;sigemptyset(&newact.sa_mask);newact.sa_flags = 0;sigaction(SIGALRM, &newact, &oldact);/* block SIGALRM and save current signal mask */sigemptyset(&newmask);sigaddset(&newmask, SIGALRM);sigprocmask(SIG_BLOCK, &newmask, &oldmask);alarm(seconds);suspmask = oldmask;/* make sure SIGALRM isn't blocked */sigdelset(&suspmask, SIGALRM);/* wait for any signal to be caught */sigsuspend(&suspmask);/* some signal has been caught, SIGALRM is now blocked */unslept = alarm(0);/* reset previous action */sigaction(SIGALRM, &oldact, NULL);/* reset signal mask, which unblocks SIGALRM */sigprocmask(SIG_SETMASK, &oldmask, NULL);return (unslept);
nanosleep
函数与sleep
函数类似,但提供了纳秒级的精度。
#include <time.h>
int nanosleep(const struct timespec *reqtp, struct timespec *remtp);
返回值:若休眠到要求的时间,返回0;若出错,返回-1。
reqtp
参数用秒和纳秒来指定需要休眠的时间长度。如果某个信号中断了休眠间隔,进程并没有终止,remtp
参数指向的timespec
结构就会被设置为未休眠完的时间长度。如果对未休眠完的时间并不感兴趣,可以设置为NULL
。
随着多个系统时钟的引入,需要使用相对于特定时钟的延迟时间来挂起调用线程。clock_nanosleep
函数提供了这种功能。
#include <time.h>
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp);
返回值:若休眠要求的时间,返回0;若出错,返回错误码。
clock_id
参数指定了计算延迟时间基于的时钟。flags
参数用于控制延迟是相对的还是绝对的。flags
为0时表示休眠时间是相对的,如果flags
为TIMER_ABSTIME
,表示休眠时间是绝对的。其他的参数reqtp
和remtp
,与nanosleep
函数中相同。但是,使用绝对时间时,remtp
参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep
调用复用reqtp
参数相同的值。
`
clock_id
参数指定了计算延迟时间基于的时钟。flags
参数用于控制延迟是相对的还是绝对的。flags
为0时表示休眠时间是相对的,如果flags
为TIMER_ABSTIME
,表示休眠时间是绝对的。其他的参数reqtp
和remtp
,与nanosleep
函数中相同。但是,使用绝对时间时,remtp
参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep
调用复用reqtp
参数相同的值。
注意: 除了出错返回,调用clock_nanosleep(CLOCK_REALTIME, 0, reqtp, remtp);
和调用 nanosleep(reqtp, remtp);
效果相同。使用相对休眠时间的问题是对于那些对休眠精度有要求的应用来说,相对休眠时间会导致实际休眠时间比要求的长,当采用绝对时间时,这样却可以很好的改善精度。
信号之函数system、sleep、nanosleep以及clock_nanosleep相关推荐
- 函数sleep、nanosleep和clock_nanosleep(UNIX环境高级编程笔记)
#include <unistd.h> unsigned int sleep(unsigned int seconds); 返回值:0或未休眠完的秒数 此函 ...
- Linux中延时/暂停函数(sleep/usleep/nanosleep/select)的比较、底层实现说明
本来只是要搞清楚Linux下如何实现延时和暂停,但无意中看到一篇文章介绍了其实现,帮自己窥得一点底层原理. 知其然还要知其所以然,但自己没有这个储备和能力来研究Linux内核实现,特地转载留存. 1. ...
- linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...
信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...
- linux exec 二程序,二十五、Linux 进程与信号---exec函数
25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...
- UNIX再学习 -- 函数 system
一.system 函数 #include <stdlib.h> int system(const char *command); 1.参数解析 command:shell 命令行字符串 2 ...
- 函数简介篇——进程创建函数:system()
说明: 本文章旨在总结备份.方便以后查询,由于是个人总结,如有不对,欢迎指正:另外,内容大部分来自网络.书籍.和各类手册,如若侵权请告知,马上删帖致歉. QQ 群 号:513683159 [相 ...
- 信号之函数的可重入性
信号之函数的可重入性 在调用某个函数过程中出现中断信号,且改信号处理函数中再次调用该函数,访问全局.静态变量的函数是不可重入函数. 前后数据不一致,函数是不可重入的,特点:函数中使用全局变量或静态变量 ...
- linux操作系统信号捕捉函数之回调函数小结
(1)signal 信号捕捉函数:注册一个信号捕捉函数(不参与捕捉,那是内核的事情) 函数实现: typedef void(*sighandler_t)(int); //声明了一个函数指针(代 ...
- linux操作系统信号捕捉函数之sigaction用法小结
(1)sigaction函数:注册一个信号捕捉函数(不参与捕捉信号,信号由内核捕捉),并修改原来的信号处理动作 (2)函数原型及头文件 头文件:#include<signal.h> 函数原 ...
最新文章
- 英语口语 week12 Thursday
- 当深度学习走进高考考场,会发生什么!!
- 近6年语音合成领域都有哪些论文?
- 使用UMDH查找内存泄漏
- JavaScript匿名函数和回调函数
- centos7中 npm install express 时Error: Cannot find module 'express'错误
- hermite插值c语言程序,张艳-埃尔米特Hermite 插值逼近的C语言程序.doc
- 智慧路灯物联网解决方案
- 第三代计算机的内存是,Intel正式发布Cooper Lake、第三代傲腾内存和新数据中心SSD...
- 职场中,什么样的人最容易升职?
- 一台显示器分成双屏_双屏办公,用起来到底有多爽
- Windows XP 系统下使用宽带上网真方便
- 大数开根 高精度 平方根
- android dialog 隐藏键盘,android dialog 隐藏虚拟按键
- 你总要一个人 走过一段艰难的日子
- 分享《Essential Linux Device Drivers》中文版高清电子版
- Unsupported major.minor version 52.0 解决方案
- Keil MDK中的Code, RO-data , RW-data, ZI-data分别代表什么意思?(转)
- 未来数字科技趋势分析与前沿热点解读
- 对BroadCastReceiver的理解