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将捕捉信号和信号处理函数集成到一起了)

sigsuspend的更多相关文章

  1. Linux C 信号 pause、sigsuspend 的相同与区别

    pause函数:       功能:让进程暂停直到信号出现   #include<unistd.h>      intpause();    函数说明:pause()会令目前的进程暂停(进 ...

  2. Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

    我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...

  3. 信号屏蔽的切换的理解sigsuspend

    #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...

  4. 实验:sigsuspend(),sigprocmask()

    实验:sigsuspend(),sigprocmask() 源代码: /* * Program: pause_suspend.c * To test the difference between si ...

  5. 信号之sigsuspend函数

    更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信 ...

  6. Linux c 信号—pause、sigsuspend 的相同于区别

    pause函数:      功能:让进程暂停直到信号出现 #include<unistd.h> intpause(); 函数说明:pause()会令目前的进程暂停(进入睡眠状态),直至信号 ...

  7. APUE读书笔记:关于sigsuspend

    sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的 ...

  8. UNIX环境高级编程——sigqueue、sigsuspend函数

    一.sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用. int sigqueue(pid_t pid, int sig, ...

  9. sigsuspend()阻塞:异步信号SIGIO为什么会被截胡?

    关键词:fcntl.fasync.signal.sigsuspend.pthread_sigmask.trace events. 此文主要是解决问题过程中的记录,内容有较多冗余.但也反映解决问题中用到 ...

  10. 【C】——利用sigsuspend函数等待信号阻塞进程

    #include<signal.h> int sigsuspend(const sigset_t *sigmask); 返回值:-,并将errno设置为EINTR 将进程的信号屏蔽字设置为 ...

随机推荐

  1. 【转载】jquery实现勾选复选框触发事件给input赋值+回显复选框

    引用:https://blog.csdn.net/rui276933335/article/details/45717461 JSP: <td class="as1"> ...

  2. day30 进程

    推荐两本书:现代操作系统和操作系统原来,学习好python以后再去研究.   并发:任务的切换,保存状态,存在io的是实现空间和时间的 重复利用 操作系统的发展历史: 第一代(1940-1955)手工 ...

  3. socketpair通信

    1.线程间通信(参考安卓源码InputTransport.cpp) #include <pthread.h> #include <sys/types.h> /* See NOT ...

  4. linux进程篇 (二) 进程的基本控制

    2. 进程的基本操作 接口函数 #include <unistd.h> //创建子进程 pid_t fork(void); //结束子进程 void exit(int status); / ...

  5. C#/STM32 WAV转byte WAV数据格式

    最近在做STM32音乐播放器,选取了最容易做的WAV格式. 为了更方便开发自己做了一个WAV转Byte的小上位机 附软件下载链接 链接:https://pan.baidu.com/s/1Zz7bczZ ...

  6. 成都Uber优步司机奖励政策(4月6日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. Mac iTem2 自动登录服务器配置

    假设你要连接的服务器地址为123.123.123.123,端口号为8888,用户名为root,密码为mimamima 编写shell文件"login_server.sh",并放置于 ...

  8. EF Core ThenInclude 2.0自动完成提示有误,坑了一下

    只要代码正确,可以编译运行的... https://github.com/dotnet/roslyn/issues/8237

  9. PHP中strtotime()的使用

    strtotime是一个非常强大的函数. 传入的参数,详见官网的介绍 本月最后一个周日 echo date('Y-m-d',strtotime('last sunday of this month') ...

  10. SpringBoot学习:整合Redis

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 pom.xml添加对redis的依赖: <!-- https://mvnrepos ...