转自
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^Csleep over,next is sigsuspendsigsuspend catch SIGINTThe 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^CI 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]$