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

2)一个保护临界区代码的错误实例:(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; //信号处理函数handler
sigemptyset(&act.sa_mask);
act.sa_flags = ;
sigaction(SIGINT, &act, ); //准备捕捉SIGINT信号
sigemptyset(&new);
sigaddset(&new, SIGINT);
sigprocmask(SIG_BLOCK, &new, &old); //将SIGINT信号阻塞,同时保存当前信号集
printf("Blocked");
sigprocmask(SIG_SETMASK, &old, NULL); //取消阻塞
pause();
return ;
}

上面实例的问题是:本来期望pause()之后,来SIGINT信号,可以结束程序;可是,如果当“取消阻塞”和“pause”之间,正好来了SIGINT信号,结果程序因为pause的原因会一直挂起。。。

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

 )使用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");
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 = ;
sigaction(SIGINT, &act, ); //可以捕捉以下三个信号:SIGINT/SIGQUIT/SIGUSR1
sigaction(SIGQUIT, &act, );
sigaction(SIGUSR1, &act, ); sigemptyset(&new);
sigaddset(&new, SIGINT); //SIGINT信号加入到new信号集中
sigemptyset(&wait);
sigaddset(&wait, SIGUSR1); //SIGUSR1信号加入wait
sigprocmask(SIG_BLOCK, &new, &old); //将SIGINT阻塞,保存当前信号集到old中 //临界区代码执行 if(sigsuspend(&wait) != -) //程序在此处挂起;用wait信号集替换new信号集。即:过来SIGUSR1信 号,阻塞掉,程序继续挂起;过来其他信号,例如SIGINT,则会唤醒程序。执行sigsuspend的原子操作。注意:如果“sigaddset(&wait, SIGUSR1);”这句没有,则此处不会阻塞任何信号,即过来任何信号均会唤醒程序。
printf("sigsuspend error");
printf("After sigsuspend");
sigprocmask(SIG_SETMASK, &old, NULL);
return ;
}

sigsuspend的原子操作是:

(1)设置新的mask阻塞当前进程(上面是用wait替换new,即阻塞SIGUSR1信号)

(2)收到SIGUSR1信号,阻塞,程序继续挂起;收到其他信号,恢复原先的mask(即包含SIGINT信号的)。

(3)调用该进程设置的信号处理函数(程序中如果先来SIGUSR1信号,然后过来SIGINT信号,则信号处理函数会调用两次,打印不同的内容。第一次打印SIGINT,第二次打印SIGUSR1,因为SIGUSR1是前面阻塞的)

(4)待信号处理函数返回,sigsuspend返回了。(sigsuspend将捕捉信号和信号处理函数集成到一起了)

最新文章

  1. MyBatis foreach标签遍历数组
  2. IOS第13天(2,私人通讯录,plist存储,偏好设置,归档)
  3. Python可变参数
  4. Java中方法与数组
  5. js prompt函数使用例子
  6. 【转】Java多线程学习
  7. nginx安装php和php-fpm
  8. py2exe生成exe后,运行exe时提示No module named * 的解决办法
  9. 数学期望和概率DP题目泛做(为了对应AD的课件)
  10. DOM操作-根据name获取网页中的全部复选框
  11. 关于REST的浅显了解
  12. jstl---&gt;Core 核心标签库-&gt;流程控制
  13. centos6.5 yum update 报错Couldn&#39;t resolve host &#39;centos.ustc.edu.cn&#39;
  14. 接入渠道SDK时出现乙方SDK回调不起作用
  15. Win10 + Ubuntu双系统,删除Ubuntu系统
  16. xampp+discuz 安装踩坑后总结
  17. iOS CATransition 动画的简单使用
  18. 使用GitHub搭建个人博客
  19. xss攻击问题以及如何防范
  20. @params、@PathVariabl和@RequestParam用法与区别

热门文章

  1. XSS攻击 &amp;&amp; CSRF攻击 基础理解
  2. MySQL集群-PXC搭建以及使用innobackupex工具进行全局备份和增量备份
  3. 15-oauth2+oidc实现Server部分
  4. C#、C++、Java、Python 选择哪个好?
  5. Strange RadioButton group behavior with ToolBar
  6. VS2015编译MapWinGIS
  7. 每天看一片代码系列(二):WebSocket-Node
  8. 3329: Xorequ
  9. 海思NB-IOT模块HI2115芯片I2C通信
  10. wireshark抓包分析——TCP/IP协议