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     signal(SIGINT, sigfunc);
13     //2-初始化信号集
14     sigemptyset(&newsigset);
15     //3-添加待处理信号集
16     sigaddset(&newsigset, SIGINT);
17     //4-设置阻塞信号集
18     sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);//先屏蔽SIGINT信号
19     //5-休眠
20     for(i=0;i<6;i++)
21     {
22         printf("sleeping %d\n",i);
23         sleep(1);
24     }
25     //6-检查获取到的被阻塞的信号集
26     sigpending(&pendsigset);
27     printf("SIGINT is blocked %d\n", sigismember(&pendsigset, SIGINT));
28     //7-还原被屏蔽的信号集
29     printf("recover signal \n");
30     sigprocmask(SIG_UNBLOCK,&newsigset,&oldsigset);//去除SIGING信号的屏蔽
31     while(1)
32     {
33         printf("i is %d\n",i++);
34         sleep(1);
35     }
36     return 0;
37 }
38
39 void sigfunc(int signum)
40 {
41     printf("catch SIGINT | signum = %d\n", signum);
42 }

程序运行结果如下:

 1 sleeping 0
 2 sleeping 1
 3 ^Csleeping 2
 4 sleeping 3
 5 sleeping 4
 6 sleeping 5
 7 SIGINT is blocked 1
 8 recover signal
 9 catch SIGINT | signum = 2   //被阻塞的信号在阻塞解除后进行信号处理
10 i is 6
11 i is 7
12 i is 8
13 i is 9
14 i is 10
15 i is 11
16 i is 12
17 ^Ccatch SIGINT | signum = 2   //解除信号后的主函数可以进行信号处理
18 i is 13
19 i is 14
20 i is 15
21 ^\Quit (core dumped)

但是这个程序有个弊端,我们为了调试方便,才在最后设置了一个while函数,如果没有while函数,该程序会顺序执行完并且推出。

如果我们想一个函数会阻塞进程直至捕获到信号,使程序不会在捕获信号前直接退出,那该是多好啊?庆幸的是,sigsuspend就是这样的函数。(终于等到你!^◊^)

 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     int i;
15     signal(SIGINT, handler);
16     sigset_t newsigset, oldsigset, suspendsigset;
17     sigemptyset(&newsigset);
18     sigemptyset(&suspendsigset);
19     sigaddset(&newsigset, SIGINT);
20     sigaddset(&suspendsigset, SIGUSR1);
21
22     sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);
23
24     for (i=0; i<5; ++i)
25     {
26         printf("sleeping i=%d\n", i);
27         sleep(1);
28     }
29
30     sigsuspend(&suspendsigset);
31
32     sigprocmask(SIG_UNBLOCK, &newsigset, &oldsigset);
33
34     return 0;
35 }
该程序运行的两种不同情况的结果如下:

sleeping i=0
sleeping i=1
sleeping i=2
sleeping i=3
sleeping i=4
^Csignum=2       //看的不那么明显,这是sleeping后一直在等待^C信号,我们输入^C信号后,程序执行信号函数操作并退出!

/test/C_language_pointer/process$ ./sigsuspend
sleeping i=0
sleeping i=1
^Csleeping i=2    //在阻塞中间段发射信号^C后,我们看到直到阻塞完成才执行信号处理函数
sleeping i=3
sleeping i=4
signum=2

时间: 2024-07-29 11:52:26

sigsuspend函数的相关文章

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()函数

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

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是一个

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

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

信号的屏蔽,信号集

1.信号集 POSIX标准定义了数据类型sigset_t #include <signal.h> int sigemptyset(sigset_t *set); 初始化一个信号集,使其不包括任何信号 int sigfillset(sigset_t *set); 用来初始化一个信号集,使其包括所有信号 int sigaddset(sigset_t *set, int signum); 用来向set指定的信号集中添加由signum指定的信号 int sigdelset(sigset_t *set,

POSIX API

POSIX标准总体分析 POSIX,全称为可移植性操作系统接口,是一种关于信息技术的IEEE标准.它包括了系统应用程序接口(API),以及实时扩展(C语言). 该标准的目的是定义了标准的基于UNIX操作系统的系统接口和环境来支持源代码级的可移植性.现在,标准主要提供了依赖C语言的一系列标准服务,再将来的版本中,标准将致力于提供基于不同语言的规范. 该标准对核心需求部分定义了一系列任何编程语言都通用的服务,这一部分服务主要从其功能需求方面阐述,而非定义依赖于编程语言的接口.语言规范主要有两部分组成