sigprocmask函数总结
2016-05-07 16:29
316 查看
首先看它的作用:
一个进程的信号屏蔽字规定了当前阻塞而给该进程的信号集。调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作。
首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回。
其次,若set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。
表10-4说明了how可选用的值。注意,不能阻塞SIGKILL和SIGSTOP信号。
表10-4 用sigprocmask更改当前信号屏蔽字的方法
如果set是空指针,则不改变该进程的信号屏蔽字,how的值也无意义。
在调用sigprocmask后如果有任何未决的、不再阻塞的信号,则在sigprocmask返回前,至少会将其中一个信号递送给该进程。
尤其注意最后这句话!!! 接下来我来说明为什么写这篇博客
我们知道, 当造成信号的事件发生,比如硬件异常(如除以0),软件条件(如alarm计时器超时)、终端产生的信号或调用kill函数产生的信号,内核向进程发送一个信号。当我们连续多次产生同一个信号,比如SIGINT信号,
系统究竟是只接受第一个而屏蔽了以后多个信号呢?还是都接收信号?我们当且敢肯定的是第一个信号是会被接收(在sigprocmask中没有屏蔽这个信号)的。此时,调用进程会转到信号处理程序中, 因为我们可以用sigprocmask来检测当前进程的信号屏蔽字的,所以我们就可以在信号处理程序中来查看此信号是否被屏蔽了。
所以我们来看一段代码,代码意思就是检测SIGINT信号, 当发生信号后转到sig_int(int) 函数中, 在pr_mask函数中,使用了sigprocmask函数来检测当前进程是否屏蔽了SIGINT信号:
接下来我们看看结果:
这里结果就出乎我的预料了。首先在没有按下ctrl+c产生SIGINT信号前, 进程中没有屏蔽SIGINT信号,而当我们产生中断信号是,由结果可以看到SIGINT信号被屏蔽了,但出人意料的是当我们多次产生中断信号的时候, 进程全部都接收了。 现在再读读
在调用sigprocmask后如果有任何未决的、不再阻塞的信号,则在sigprocmask返回前,至少会将其中一个信号递送给该进程。
也就是说,因为程序中我们并没有屏蔽中断信号,而当进程在处理中断信号的时候是屏蔽了接下来的中断信号,所以在信号处理函数中会有SIGINT出现, 而当信号处理函数完成,准确的说是sigprocmask完成前, 接下来的SIGINT都会被接收处理.
另外, 当进程处于休眠状态时, 当有信号发生时, 也会让进程苏醒过来, 这个接下来考虑一下。
一个进程的信号屏蔽字规定了当前阻塞而给该进程的信号集。调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作。
#include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1
首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回。
其次,若set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。
表10-4说明了how可选用的值。注意,不能阻塞SIGKILL和SIGSTOP信号。
表10-4 用sigprocmask更改当前信号屏蔽字的方法
how | 说明 |
SIG_BLOCK | 该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集。set包含了我们希望阻塞的附加信号 |
SIG_UNBLOCK | 该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集补集的交集。set包含了我希望解除阻塞的信号 |
SIG_SETMASK | 该进程新的信号屏蔽字将被set指向的信号集的值代替 |
在调用sigprocmask后如果有任何未决的、不再阻塞的信号,则在sigprocmask返回前,至少会将其中一个信号递送给该进程。
尤其注意最后这句话!!! 接下来我来说明为什么写这篇博客
我们知道, 当造成信号的事件发生,比如硬件异常(如除以0),软件条件(如alarm计时器超时)、终端产生的信号或调用kill函数产生的信号,内核向进程发送一个信号。当我们连续多次产生同一个信号,比如SIGINT信号,
系统究竟是只接受第一个而屏蔽了以后多个信号呢?还是都接收信号?我们当且敢肯定的是第一个信号是会被接收(在sigprocmask中没有屏蔽这个信号)的。此时,调用进程会转到信号处理程序中, 因为我们可以用sigprocmask来检测当前进程的信号屏蔽字的,所以我们就可以在信号处理程序中来查看此信号是否被屏蔽了。
所以我们来看一段代码,代码意思就是检测SIGINT信号, 当发生信号后转到sig_int(int) 函数中, 在pr_mask函数中,使用了sigprocmask函数来检测当前进程是否屏蔽了SIGINT信号:
#include <stdio.h> #include <signal.h> void sig_int( int ); void pr_mask( const char *); //call to funtion pr_mask int main(int argc , char *argv[]){ setbuf( stdout , NULL ); //close buffer pr_mask( "before catching signal ,mask sig :" ); if( signal( SIGINT , sig_int ) == SIG_ERR ) oops( "signal" ); //keep loop to catch signal interuption while(1) // pause(); sleep( 3 ); pr_mask( "end catching signal ,mask sig :" ); return 0; } //signal handler void sig_int( int signo ){ pr_mask( "in signal handler:" ); }pr_mask函数和oops函数如下:
#include <stdio.h> #include <errno.h> #include <signal.h> void pr_mask( const char *str ){ sigset_t set; int errno_save; //get the pre errno errno_save = errno; if( sigprocmask( 0, NULL , &set ) == -1 ) oops( " sigmask" ); else{ printf( "\n%s" , str ); if( sigismember( &set , SIGQUIT ) ) printf( " SIGQUIT" ); if( sigismember( &set , SIGINT ) ) printf( " SIGINT" ); if( sigismember( &set , SIGUSR1 ) ) printf( " SIGUSR1" ); if( sigismember( &set , SIGALRM ) ) printf( " SIGALRM" ); } errno = errno_save ; }
#include <stdio.h> #include <stdlib.h> void oops(void *msg){ perror(msg); exit(1); }
接下来我们看看结果:
这里结果就出乎我的预料了。首先在没有按下ctrl+c产生SIGINT信号前, 进程中没有屏蔽SIGINT信号,而当我们产生中断信号是,由结果可以看到SIGINT信号被屏蔽了,但出人意料的是当我们多次产生中断信号的时候, 进程全部都接收了。 现在再读读
在调用sigprocmask后如果有任何未决的、不再阻塞的信号,则在sigprocmask返回前,至少会将其中一个信号递送给该进程。
也就是说,因为程序中我们并没有屏蔽中断信号,而当进程在处理中断信号的时候是屏蔽了接下来的中断信号,所以在信号处理函数中会有SIGINT出现, 而当信号处理函数完成,准确的说是sigprocmask完成前, 接下来的SIGINT都会被接收处理.
另外, 当进程处于休眠状态时, 当有信号发生时, 也会让进程苏醒过来, 这个接下来考虑一下。
相关文章推荐
- <html>文档类型
- NYOJ - 会场安排问题
- HDU_1227_Fast Food_动态规划
- 利用arduino 控制舵机转动
- 单调旋转数组的TopK问题
- C++实验5-数组分离
- java的路径研究
- 框架选择的原因及其说明
- Elasticsearch+Logstash+Kibana教程
- 个位数统计
- xml解析-jaxp-sax方式
- Struts2中的struts.i18n.encoding的较量
- 欧拉函数
- Java简单实例--小超市
- 共享内存的常用函数原理剖析
- Difference Between Hard & Soft Links
- ios开发之NSTimer 详细设置
- 《逃离德黑兰》
- VS 数组遇到的问题
- 创建一个内容提供者Creating a Content Provider——翻译总结自developer.android.com