sigsuspend

sigsuspend的主要作用就是阻塞进程直至捕获到信号,在讲该函数前先回顾一下上一篇介绍的下信号延迟处理的方法,先贴一下上一篇文章中的实现代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <signal.h>
 5 #include <unistd.h>
 6 void sigfunc(int signum);
 7 int main()
 8 {
 9     sigset_t newsigset, oldsigset, pendsigset;
10     //1-设置捕获信号
11     signal(SIGINT, sigfunc);
12     //2-初始化信号集
13     sigemptyset(&newsigset);
14     //3-添加待处理信号集
15     sigaddset(&newsigset, SIGINT);
16     //4-设置阻塞信号集
17     sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);
18     //5-休眠
19     for (int i=0; i<5; ++i)
20     {
21         printf("sleeping %d\n", i);
22         sleep(1);
23     }
24     //6-检查获取到的被阻塞的信号集
25     sigpending(&pendsigset);
26     printf("SIGINT is blocked %d\n", sigismember(&pendsigset, SIGINT));
27     //7-还原被屏蔽的信号集
28     printf("recover signal \n");
29     sigprocmask(SIG_SETMASK, &oldsigset, 0);
30     return 0;
31 }
32
33 void sigfunc(int signum)
34 {
35     printf("catch SIGINT | signum = %d\n", signum);
36 }

上述代码中,在sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);后休眠了5秒,如果在5秒内收到SIGINT的话则该信号会延迟到5秒之后的sigprocmask(SIG_SETMASK, &oldsigset, 0);之后处理,但如果5秒内没有收到SIGINT信号,程序顺序执行,直接退出。即使在sigprocmask(SIG_SETMASK, &oldsigset, 0);之后添加pause,那么也可能在两个之间收到SIGINT信号,从而导致程序一直处于pause状态。

而sigsuspend则可以解决上述问题。sigsuspend会阻塞进程直至捕获到信号,使程序不会在捕获信号前直接退出,又由于是原子操作,所以不会出现在sigprocmask(SIG_SETMASK, &oldsigset, 0);和pause中间出现SIGINT导致进程一直pause。

示例代码如下:

 1 #include <signal.h>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #include <unistd.h>
 6
 7 void handler(int signum)
 8 {
 9     printf("signum=%d\n", signum);
10 }
11
12 int main()
13 {
14     signal(SIGINT, handler);
15     sigset_t newsigset, oldsigset, suspendsigset;
16     sigemptyset(&newsigset);
17     sigemptyset(&suspendsigset);
18     sigaddset(&newsigset, SIGINT);
19     sigaddset(&suspendsigset, SIGUSR1);
20
21     sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);
22
23     for (int i=0; i<5; ++i)
24     {
25         printf("sleeping i=%d\n", i);
26         sleep(1);
27     }
28
29     sigsuspend(&suspendsigset);
30
31     sigprocmask(SIG_SETMASK, &oldsigset, NULL);
32
33     return 0;
34 }
时间: 2024-08-03 16:18:01

sigsuspend的相关文章

Linux进程间通信 -- 信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我们需要处理的信号,我们不需要处理哪些信号等问题呢?信号集函数就是帮助我们解决这些问题的. 有关Linux进程间使用信号通信的更多内容,可以参阅我的另一篇文章,Linux进程间通信 -- 信号量函数 signal().sigaction() 下面是信号函数集: 1.int sigemptyset(si

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

pause函数:       功能:让进程暂停直到信号出现   #include<unistd.h>      intpause();    函数说明:pause()会令目前的进程暂停(进入睡眠状态),直至信号(signal)所中断. 返回值:只返回-1. #include<stdio.h> #include<unistd.h> void deal() { printf(“信号干扰!\n”); } void main() { printf(“进程执行!\n”); sig

sigsuspend函数

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <signal.h> 5 #include <unistd.h> 6 void sigfunc(int signum); 7 int main() 8 { 9 int i; 10 sigset_t newsigset, oldsigset, pendsigset; 11 //1-设置捕获信号 12

sigprocmask , sigpending 和 sigsuspend函数

转自 http://blog.csdn.net/elbort/article/details/7594772 sigprocmask函数: 功能描述:设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). 用法:#include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); NOTE: If oldset is non-null, the previous value of the sign

sigsuspend sigprocmask函数的用法

一个进程的信号屏蔽字规定了当前堵塞而不能递送给该进程的信号集.调用函数sigprocmask能够检測或更改其信号屏蔽字,或者在一个步骤中同一时候运行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是

sigsuspend sigprocmask函数的使用方法

一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集.调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是一个

APUE读书笔记:关于sigsuspend

sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生.这样来看与另一个函数的作用相同.pause() 加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进

linux c编程:信号(五) sigsuspend

更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信号时SIGINT,实现这一点的一种不正确的方法是: sigset_t    newmask, oldmask; sigemptyset(&newmask); sigaddset(&newmask, SIGINT); /* block SIGINT and save current signal

sigsuspend()函数

在学习sigsuspend()函数时存在一些迷惑,并不太理解书上所叙述的内容.最终,结合网上资源对该函数慢慢有了一点理解,记录下来,以备以后补充. 在<UNIX环境高级编程>中该函数的提出是在解除信号屏蔽(这里以SIGINT为例)时,信号立即发生,没有等待到pause函数执行的情况下. sigset_t newmask,oldmask;sigemptyset(&newmask);sigaddset(&newmask,SIGINT); if(sigprocmask(SIG_BLO