sigsuspend()函数 解释
sigsuspend函数作用 :如果在等待信号发生时希望去休眠,则使用sigsuspend函数是非常合适的
头文件:#include <signal.h>
一个保护临界区代码的错误实例:(sigprocmask()和pause()实现)
#include <unistd.h>
#include <signal.h>
#include <stdio.h>void handler(int sig) //信号处理函数的实现
{printf("SIGINT sig");
}
int main()
{sigset_t new,old;struct sigaction act;act.sa_handler = handler; //信号处理函数handlersigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGINT, &act, 0); //准备捕捉SIGINT信号sigemptyset(&new);sigaddset(&new, SIGINT);sigprocmask(SIG_BLOCK, &new, &old); //将SIGINT信号阻塞,同时保存当前信号集printf("Blocked");sigprocmask(SIG_SETMASK, &old, NULL); //取消阻塞pause();return 0;
}
上面实例的问题是:本来期望pause()之后,来SIGINT信号,可以结束程序;可是,如果当“取消阻塞”和“pause”之间,正好来了SIGINT信号,结果程序因为pause的原因会一直挂起。。。
如果在信号阻塞时将其发送给进程,那么该信号的传递就被推迟直到对它解除了阻塞。对应用程序而言,该信号好像发生在解除对SIGINT的阻塞和pause之间。如果发生了这种情况,或者如果在解除阻塞时刻和pause之间确实发生了信号,那么就产生了问题。因为我们可能不会再见到该信号,所以从这种意义上而言,在此时间窗口(解除阻塞和pause之间)中发生的信号丢失了,这样就使pause永远阻塞。
为了纠正此问题,需要在一个原子操作中先恢复信号屏蔽字,然后使进程休眠。这种功能是由sigsuspend函数提供的。
#include <signal.h>int sigsuspend( const sigset_t *sigmask ); 返回值:-1,并将errno设置为EINTR
将进程的信号屏蔽字设置为由sigmask指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,并且将该进程的信号屏蔽字设置为调用sigsuspend之前的值。
注意,此函数没有成功返回值。如果它返回到调用者,则总是返回-1,并将errno设置为EINTR(表示一个被中断的系统调用)。
3)使用sigsuspend()的程序
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void handler(int sig) //信号处理程序
{if(sig == SIGINT)printf("SIGINT sig");else if(sig == SIGQUIT)printf("SIGQUIT sig");elseprintf("SIGUSR1 sig");
}int main()
{sigset_t new,old,wait; //三个信号集struct sigaction act;act.sa_handler = handler;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGINT, &act, 0); //可以捕捉以下三个信号:SIGINT/SIGQUIT/SIGUSR1sigaction(SIGQUIT, &act, 0);sigaction(SIGUSR1, &act, 0);sigemptyset(&new);sigaddset(&new, SIGINT); //SIGINT信号加入到new信号集中sigemptyset(&wait);sigaddset(&wait, SIGUSR1); //SIGUSR1信号加入waitsigprocmask(SIG_BLOCK, &new, &old); //将SIGINT阻塞,保存当前信号集到old中//临界区代码执行 if(sigsuspend(&wait) != -1) //程序在此处挂起;用wait信号集替换new信号集。即:过来SIGUSR1信 号,阻塞掉,程序继续挂起;过来其他信号,例如SIGINT,则会唤醒程序。执行sigsuspend的原子操作。注意:如果“sigaddset(&wait, SIGUSR1);”这句没有,则此处不会阻塞任何信号,即过来任何信号均会唤醒程序。printf("sigsuspend error");printf("After sigsuspend");sigprocmask(SIG_SETMASK, &old, NULL);return 0;
}
sigsuspend的原子操作是:
(1)设置新的mask阻塞当前进程(上面是用wait替换new,即阻塞SIGUSR1信号)
(2)收到SIGUSR1信号,阻塞,程序继续挂起;收到其他信号,恢复原先的mask(即包含SIGINT信号的)。
(3)调用该进程设置的信号处理函数(程序中如果先来SIGUSR1信号,然后过来SIGINT信号,则信号处理函数会调用两次,打印不同的内容。第一次打印SIGINT,第二次打印SIGUSR1,因为SIGUSR1是前面阻塞的)
(4)待信号处理函数返回,sigsuspend返回了。(sigsuspend将捕捉信号和信号处理函数集成到一起了)
注:sigsuspend实际是将sigprocmask和pause结合起来原子操作。
转自:http://blog.sina.com.cn/s/blog_6af9566301013xp4.html 和http://www.cnblogs.com/nufangrensheng/category/543313.html
sigsuspend()函数 解释相关推荐
- Linux信号实现精确到微秒的sleep函数:通过sigsuspend函数解决时序竞态问题
原理就是先使用定时器定时,然后再使用pause函数或者sigsuspend函数主动阻塞挂起,最终恢复现场. 如果使用pause函数的话,优点是使用简单,缺点是有可能产生时序竞态,导致进程一直阻塞下去: ...
- sigsuspend函数(mysleep函数的改进)
可以通过设置屏蔽SIGALRM的方法来控制程序执行逻辑,但无论如何设置,程序都有可能在"解除信号屏蔽"与"挂起等待信号"这个两个操作间隙失去cpu资源.除非将这 ...
- 回旋矩形C语言,C语言回旋函数解释下,该如何处理
当前位置:我的异常网» C语言 » C语言回旋函数解释下,该如何处理 C语言回旋函数解释下,该如何处理 www.myexceptions.net 网友分享于:2013-06-08 浏览:30次 C ...
- sigprocmask , sigpending 和 sigsuspend函数
sigprocmask函数: 功能描述: 设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). 用法: #include <signal.h> int sigprocmask(int ho ...
- 信号驱动任务执行(pause、sigsuspend函数)
信号驱动任务指的是通过信号来驱动任务的执行,每发送一次信号,任务就执行一次.实现该目的所需的函数就是 pause 或者 sigsuspend,pause和sigsuspend函数可以暂停当前进程,直至 ...
- matlab中bwmorph函数的作用,Matlab中的bwmorph函数解释
Matlab中的bwmorph函数解释 bwmorph:对二值图像的形态学操作. BW2 = bwmorph(BW,operation) BW2 =bwmorph(BW,operation,n) BW ...
- CreateFile函数解释
CreateFile函数解释 API函数CreateFile可打开和创建文件.管道.邮槽.通信服务.设备以及控制台,但是在此时只是介绍用这个函数怎么实现创建和打开一个文件. HANDLE Create ...
- Unix/Linux编程:竞态条件与sigsuspend函数
利用pause和alarm函数实现sleep #include <unistd.h>int pause(void); pause函数使调用进程挂起直到有信号到达.如果信号的处理动作是终止进 ...
- 10.16 sigsuspend函数
我们已经学习了如何修改进程的信号掩码,实现指定信号的阻塞与接触阻塞.我们可以使用这一技术来保护临界区域的代码(当在这一段区域内执行代码的时候哦,我们不希望被信号中断),但是如果我们想要接触一个信号的阻 ...
最新文章
- Caffe官方教程翻译(10):Editing model parameters
- The import java.util cannot be resolved
- Spring配置文件-Bean实例化的三种方式
- python接口自动化测试(二)-requests.get()
- js中四种创建对象的方式
- LintCode Find the Weak Connected Component in the Directed Graph
- mp4v2 写mp4 java_使用mp4v2将H264+AAC合成mp4文件
- Github PageHelper 原理解析
- CMD执行命令出现NOMALY: meaningless REX prefix used以及IDEA提示Cannot run git问题解决
- paip.ASP 开发调试大总结
- SQLyog注册激活码
- E盾V60原版网络验证包含个人动手改IP地址源码软件加密一机一码
- 工作环境的改善---提高工作效率和工作质量
- 【Jquery】Jquery操作table表格详细说明
- 放眼看政策!2022年武汉市光谷招贤令奖励补贴政策以及申报条件!
- 22考研全年备考规划表,这5个时间点你必须知道!
- Java将html转换成pdf、html转换成图片
- 经典同态加密算法Paillier解读 - 原理、实现和应用
- PTA单链表 - 20. 单值化(去重)
- docker的容器下使用apt-get update卡在[0%] Working问题解决办法
热门文章
- Linux之Ubuntu入门篇
- 【数字信号处理】卷积编程实现 ( 卷积计算原理 | 卷积公式计算 | 使用 matlab 计算卷积 | 使用 C 语言实现卷积计算 )
- 几种简单卷积计算方法实例-Faltung
- ORACLE这门武功
- JS中函数式编程详解版(FunctionalProgramming,FP)
- 你就像烟火的美丽,那么美丽
- Excel中HLOOKUP函数实例(一):自动判断并获取数据
- sonarqube更新最新包含阿里p3c的pmd插件
- js跳出循环的三种方法
- Redis学习笔记之十:Redis用作消息队列