博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sigsuspend()函数作用详解
阅读量:4130 次
发布时间:2019-05-25

本文共 2313 字,大约阅读时间需要 7 分钟。

来自:

看到网上大部分解释都是抄来抄去的,结果说不清楚,最后还是不理解,于是花了几个小时研究了下,感觉大体上明白了。希望本文能对你有用处。

1)头文件:#include <signal.h>

2)一个保护临界区代码的错误实例:(sigprocmask()和pause()实现)

#include 
#include
#include
void handler(int sig) //信号处理函数的实现{ printf("SIGINT sig");}int main(){ sigset_t new,old; struct sigaction act; act.sa_handler = handler; //信号处理函数handler sigemptyset(&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的原因会一直挂起。。。

解决的方式,当然是sigsuspend()函数了。

3)使用sigsuspend()的程序

#include 
#include
#include
void handler(int sig) //信号处理程序{ if(sig == SIGINT) printf("SIGINT sig"); else if(sig == SIGQUIT) printf("SIGQUIT sig"); else printf("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/SIGUSR1 sigaction(SIGQUIT, &act, 0); sigaction(SIGUSR1, &act, 0); sigemptyset(&new); sigaddset(&new, SIGINT); //SIGINT信号加入到new信号集中 sigemptyset(&wait); sigaddset(&wait, SIGUSR1); //SIGUSR1信号加入wait sigprocmask(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阻塞当前进程(ss: 应该说线程挂起,设置新的mask(信号掩码,信号阻塞集)比较合适)(上面是用wait替换new,即阻塞SIGUSR1信号)

(ss:(1)线程挂起,设置新的mask(信号掩码,信号阻塞集),即:过来wait信号集中的信号SIGUSR1,阻塞该信号;别的信号不阻塞)

(2)收到SIGUSR1信号,阻塞(ss:阻塞该信号)程序继续挂起;收到其他信号,恢复原先的mask(即包含SIGINT信号的)。
(3)调用该进程设置的信号处理函数(程序中如果先来SIGUSR1信号,然后过来SIGINT信号,则信号处理函数会调用两次,打印不同的内容。第一次打印SIGINT,第二次打印SIGUSR1,因为SIGUSR1是前面阻塞的)
(4)待信号处理函数返回,sigsuspend返回了。(sigsuspend将捕捉信号和信号处理函数集成到一起了)

转载地址:http://pcdvi.baihongyu.com/

你可能感兴趣的文章
leetcode刷题198 打家劫舍 House Robber(简单) Python Java
查看>>
NG深度学习第一门课作业2 通过一个隐藏层的神经网络来做平面数据的分类
查看>>
leetcode刷题234 回文链表 Palindrome Linked List(简单) Python Java
查看>>
NG深度学习第二门课作业1-1 深度学习的实践
查看>>
Ubuntu下安装Qt
查看>>
Qt札记
查看>>
我的vimrc和gvimrc配置
查看>>
hdu 4280
查看>>
禁止使用类的copy构造函数和赋值操作符
查看>>
C++学习路线
查看>>
私有构造函数
查看>>
组队总结
查看>>
TitledBorder 设置JPanel边框
查看>>
DBCP——开源组件 的使用
查看>>
抓包工具
查看>>
海量数据相似度计算之simhash和海明距离
查看>>
DeepLearning tutorial(5)CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
查看>>
DeepLearning tutorial(6)易用的深度学习框架Keras简介
查看>>
DeepLearning tutorial(7)深度学习框架Keras的使用-进阶
查看>>
流形学习-高维数据的降维与可视化
查看>>