本文来自个人博客:https://dunkwan.cn

文章目录

  • 函数`system`
  • 函数`sleep`、`nanosleep`和`clock_nanosleep`

函数system

由于system执行的命令可能是交互式的命令,因为system的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system的调用者就不应接收SIGINTSIGQUIT这两个终端产生的信号。

测试示例1:

system实现版本一,为考虑忽略SIGINTSIGQUIT信号。

#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);
}

结果如下:

函数sleepnanosleepclock_nanosleep

sleep函数定义如下:

#include <unistd.h>
unsigned int sleep(unsigned int seconds);
返回值:0或未休眠完的秒数。

此函数使调用进程被挂起直到满足下面两个条件之一。

  1. 已经过了seconds所指定的墙上时钟时间。
  2. 调用进程捕捉到一个信号并从信号处理程序返回。

以下是一个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时表示休眠时间是相对的,如果flagsTIMER_ABSTIME,表示休眠时间是绝对的。其他的参数reqtpremtp,与nanosleep函数中相同。但是,使用绝对时间时,remtp参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep调用复用reqtp参数相同的值。

`

clock_id参数指定了计算延迟时间基于的时钟。flags参数用于控制延迟是相对的还是绝对的。flags为0时表示休眠时间是相对的,如果flagsTIMER_ABSTIME,表示休眠时间是绝对的。其他的参数reqtpremtp,与nanosleep函数中相同。但是,使用绝对时间时,remtp参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep调用复用reqtp参数相同的值。

注意: 除了出错返回,调用clock_nanosleep(CLOCK_REALTIME, 0, reqtp, remtp); 和调用 nanosleep(reqtp, remtp);效果相同。使用相对休眠时间的问题是对于那些对休眠精度有要求的应用来说,相对休眠时间会导致实际休眠时间比要求的长,当采用绝对时间时,这样却可以很好的改善精度。

信号之函数system、sleep、nanosleep以及clock_nanosleep相关推荐

  1. 函数sleep、nanosleep和clock_nanosleep(UNIX环境高级编程笔记)

    #include <unistd.h> unsigned int sleep(unsigned int seconds);               返回值:0或未休眠完的秒数   此函 ...

  2. Linux中延时/暂停函数(sleep/usleep/nanosleep/select)的比较、底层实现说明

    本来只是要搞清楚Linux下如何实现延时和暂停,但无意中看到一篇文章介绍了其实现,帮自己窥得一点底层原理. 知其然还要知其所以然,但自己没有这个储备和能力来研究Linux内核实现,特地转载留存. 1. ...

  3. linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

  4. linux exec 二程序,二十五、Linux 进程与信号---exec函数

    25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...

  5. UNIX再学习 -- 函数 system

    一.system 函数 #include <stdlib.h> int system(const char *command); 1.参数解析 command:shell 命令行字符串 2 ...

  6. 函数简介篇——进程创建函数:system()

    说明:   本文章旨在总结备份.方便以后查询,由于是个人总结,如有不对,欢迎指正:另外,内容大部分来自网络.书籍.和各类手册,如若侵权请告知,马上删帖致歉.   QQ 群 号:513683159 [相 ...

  7. 信号之函数的可重入性

    信号之函数的可重入性 在调用某个函数过程中出现中断信号,且改信号处理函数中再次调用该函数,访问全局.静态变量的函数是不可重入函数. 前后数据不一致,函数是不可重入的,特点:函数中使用全局变量或静态变量 ...

  8. linux操作系统信号捕捉函数之回调函数小结

    (1)signal 信号捕捉函数:注册一个信号捕捉函数(不参与捕捉,那是内核的事情) 函数实现: typedef   void(*sighandler_t)(int);   //声明了一个函数指针(代 ...

  9. linux操作系统信号捕捉函数之sigaction用法小结

    (1)sigaction函数:注册一个信号捕捉函数(不参与捕捉信号,信号由内核捕捉),并修改原来的信号处理动作 (2)函数原型及头文件 头文件:#include<signal.h> 函数原 ...

最新文章

  1. 英语口语 week12 Thursday
  2. 当深度学习走进高考考场,会发生什么!!
  3. 近6年语音合成领域都有哪些论文?
  4. 使用UMDH查找内存泄漏
  5. JavaScript匿名函数和回调函数
  6. centos7中 npm install express 时Error: Cannot find module 'express'错误
  7. hermite插值c语言程序,张艳-埃尔米特Hermite 插值逼近的C语言程序.doc
  8. 智慧路灯物联网解决方案
  9. 第三代计算机的内存是,Intel正式发布Cooper Lake、第三代傲腾内存和新数据中心SSD...
  10. 职场中,什么样的人最容易升职?
  11. 一台显示器分成双屏_双屏办公,用起来到底有多爽
  12. Windows XP 系统下使用宽带上网真方便
  13. 大数开根 高精度 平方根
  14. android dialog 隐藏键盘,android dialog 隐藏虚拟按键
  15. 你总要一个人 走过一段艰难的日子
  16. 分享《Essential Linux Device Drivers》中文版高清电子版
  17. Unsupported major.minor version 52.0 解决方案
  18. Keil MDK中的Code, RO-data , RW-data, ZI-data分别代表什么意思?(转)
  19. 未来数字科技趋势分析与前沿热点解读
  20. 对BroadCastReceiver的理解

热门文章

  1. 工程建筑行业数据治理实践漫谈
  2. 计算机发展史-计算机基础知识总结(下)
  3. MySQL介绍-安装-登录
  4. 名声在外的汽车之家,为何难以吞下汽车金融市场?
  5. 马术路线设计相关的论文
  6. 3蛋白wb_IHC、ELISA和WB区别
  7. java多线程学习(超详细吐血总结)
  8. 纪中DAY10做题小结
  9. [编程题]手机屏幕解锁模式vivo笔试题
  10. 《重新认识你自己》——拒绝向导,认识自己