博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sigprocmask , sigpending 和 sigsuspend函数
阅读量:5949 次
发布时间:2019-06-19

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

转自 

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 signal mask is stored in oldset.
参数:
how:用于指定信号修改的方式,可能选择有三种
SIG_BLOCK       //加入信号到进程屏蔽。
SIG_UNBLOCK     //从进程屏蔽里将信号删除。

SIG_SETMASK     //将set的值设定为新的进程屏蔽。

相应函数命令:

sigset_t set

sigemptyset(&set) :清空阻塞信号集合变量

sigfillset(&set) :添加所有的信号到阻塞集合变量里

sigaddset(&set,SIGINT):添加单一信号到阻塞信号集合变量

sigdelset(&set,SIGINT):从阻塞信号集合变量中删除单一信号

sigismember(&set,int signum):这个函数测试信号signum是否包含在信号集合set中,如果包含返回1,不包含返回0,出错返回-1。错误代码也只有一个EINVAL,表示signum不是有效的信号代码。

代码说明:最简单的一个例子

#include 
#include
int main(){ sigset_t set; //定义阻塞信号集的变量 sigemptyset(&set); //清空变量set的阻塞信号 sigaddset(&set,SIGINT); //添加将要阻塞的信号"SIGINT"到阻塞信号集变量 sigdelset(&set,SIGINT); //从已有的阻塞信号集变量中删除阻塞信号"SIGINT" sigaddset(&set,SIGQUIT); //添加将要阻塞的信号"SIGQUIT"到阻塞信号集变量 sigprocmask(SIG_SETMASK,&set,NULL);// 将当前的阻塞信号集合变量set设置为该进程信号阻塞列表 while(1); // return 0;}

结果显示:

[elbort@elbort test1]$ ./test

^\^\
^C
[elbort@elbort test1]$

说明: ^\   键盘上是ctrl + \  对应信号 SIGQUIT

             ^c  键盘上是ctrl + c 对应信号 SIGINT

该结果说明test进程屏蔽了信号SIGQUIT,没有屏蔽信号SIGINT。 

sigpending 函数:

功能:返回在阻塞期间接收到阻塞信号的集合。

代码说明:

#include 
#include
#include
#include
int main( void ) { sigset_t set, oset, pset; sigemptyset( &set ); sigaddset( &set, SIGINT ); sigaddset(&set,SIGQUIT); sigaddset(&set,SIGABRT); sigprocmask( SIG_BLOCK, &set, &oset ); printf( "Old set was %8.8ld.\n", oset ); printf( "set is %8.8ld.\n", set ); sigpending( &pset ); printf( "Pending set is %8.8ld.\n", pset ); kill( getpid(), SIGINT ); sigpending( &pset ); printf( "Pending set is %8.8ld.\n", pset ); kill( getpid(), SIGQUIT ); sigpending( &pset ); printf( "Pending set is %8.8ld.\n", pset ); kill( getpid(), SIGABRT ); sigpending( &pset ); printf( "Pending set is %8.8ld.\n", pset );// sigprocmask( SIG_UNBLOCK, &set, &oset ); if(sigismember(&pset,SIGINT) == 1) { printf("SIGINT was came.\n"); } if(sigismember(&pset,SIGQUIT) == 1) { printf("SIGQUIT was came.\n"); } if(sigismember(&pset,SIGABRT) == 1) { printf("SIGABRT was came.\n"); } /* The program terminates with a SIGINT */ return( EXIT_SUCCESS ); }

运行结果:

[elbort@elbort test1]$ ./test2

Old set was 00000000.
set is  00000038.
Pending set is 00000000.
Pending set is 00000002.
Pending set is 00000006.
Pending set is 00000038.
SIGINT was came.
SIGQUIT was came.
SIGABRT was came.
[elbort@elbort test1]$ 

注意:红色那句去掉//会得到完全不同的结果。为什么??

 //测试后,发现真的是

SIGINT was came.

SIGQUIT was came.
SIGABRT was came. 这三句话没有打印出来,不太好理解啊,sigprocmask( SIG_UNBLOCK, &set, &oset );这句话是解除进程的信号屏蔽set,此时阻塞的SIGINT,SIGQUIT,SIGABRT信号在sigprocmask返回之前被投递到进程,没有未决的信号了。 

sigsuspend函数

功能:它有一套属于自己的屏蔽信号mask,能够选择性接收某些信号。在接收到可行信号(也即是没有被屏蔽的信号)之前,运行到它时,它会一直挂起,有点类似pause()函数。接受到可行信号后,或者中断进程的信号,它会退出挂起并执行相应的信号函数。接收到的信号源:1.之前运行sigprocmask()函数中阻塞的信号;2.挂起后接受到的信号。

代码说明: Example:sigsuspend (Correct Way to Wait for Single Signal)

 

sigset_t maskall, maskmost, maskold;intsignum = SIGUSR1;sigfillset(&maskall); sigfillset(&maskmost);sigdelset(&maskmost,signum);sigprocmask(SIG_SETMASK,&maskall, &maskold);sigsuspend(&maskmost);sigprocmask(SIG_SETMASK,&maskold, NULL);

sigsuspend的整个原子操作过程为:

(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。 

具体例子说明:

#include 
#include
#include
void fun_int(){ printf("\nsigsuspend catch SIGINT\n"); printf("The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test\n"); sleep(5); return;}int main(){ sigset_t set; sigfillset(&set); signal(SIGINT,fun_int); sigprocmask(SIG_SETMASK,&set,NULL); sigdelset(&set,SIGINT); printf("Here is the sigprocmask signal block,before use sigsuspend\n"); sleep(5); printf("\nsleep over,next is sigsuspend\n"); sigsuspend(&set); printf("\nI have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask\n"); sleep(10); printf("\nTest finish\n"); return 0;}

结果显示:

[elbort@elbort test1]$ ./test

Here is the sigprocmask signal block,before use sigsuspend
^\^\^\
^C^C^C
sleep over,next is sigsuspend
sigsuspend catch SIGINT
The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test
^C^C^C
I have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask
^C^C^C^\^\^\
Test finish
[elbort@elbort test1]$

转载于:https://www.cnblogs.com/QingCHOW/p/4594862.html

你可能感兴趣的文章
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>
通过jsp请求Servlet来操作HBASE
查看>>
crontab执行shell脚本日志中出现乱码
查看>>
Shell编程基础
查看>>
Shell之Sed常用用法
查看>>
3.1
查看>>
校验表单如何摆脱 if else ?
查看>>
JS敏感信息泄露:不容忽视的WEB漏洞
查看>>
分布式memcached服务器代理magent安装配置(CentOS6.6)
查看>>
Create Volume 操作(Part III) - 每天5分钟玩转 OpenStack(52)
查看>>