Linux Signal (6): 信号屏蔽字

[手动搬家自网易博客 原发表日期:2008-03-01]

1. 概念:

信号屏蔽字就是进程中被阻塞的信号集, 这些信号不能发送给该进程, 它们在该进程中被"屏蔽"了. 后面我们会提到, 实际上它们是被阻塞了.

2. 信号屏蔽函数:

#include  < signal.h > int  sigprocmask( int  how,  const  sigset_t  * restrict  set , sigset_t  * restrict oset); 成功则返回0, 出错则返回 - 1 .

sigprocmask函数有3个参数:

  • how: 修改信号屏蔽字的方式.
  • set: 把这个信号集设为新的当前信号屏蔽字. 如果为NULL则不改变.
  • oset: 保存进程旧的信号屏蔽字. 如果为NULL则不保存.

参数中的how可以取3个值:

sigprocmask中的how参数
how 说明
SIG_BLOCK 修改后, 该进程新的信号屏蔽字是其当前屏蔽字和set指向的信号集的并集.
SIG_UNBLOCK 修改后, 该进程新的信号屏蔽字是其当前屏蔽字和set指向的信号集的补集的交集.
SIG_SETMASK 修改后, 该进程新的信号屏蔽字将被set指向的信号集的值代替

 另外要说的是, sigprocmask只为单线程定义的, 在多线程中要使用pthread_sigmask.

3. 未处理的信号:

在调用信号屏蔽的相关函数后, 被屏蔽的信号对于调用进程是阻塞的, 不能发送给调用进程, 因此是未决的. 取得这些阻塞的信号集, 可以通过调用sigpending函数.

#include  < signal.h > int  sigpending(sigset_t  * set ); 成功则返回0, 出错则返回 - 1 .

4. 实例:

下面通过一个简单的实例来说明这篇文章中所讲到的两个函数.

#include  < signal.h > #include  < unistd.h > #include  < stdlib.h > #include  < stdio.h > /*  SIGQUIT handler  */ static   void  sig_quit( int  signo) {     printf( " SIGQUIT is caught " ); } int  main() {     sigset_t  new , old, pend;      /*  Handle SIGQUIT  */      if  (signal(SIGQUIT, sig_quit)  ==  SIG_ERR)     {         perror( " signal " );         exit( 1 );     }      /*  Add SIGQUIT to sigset  */      if  (sigemptyset( & new <   0 )         perror( " sigemptyset " );      if  (sigaddset( & new , SIGQUIT)  <   0 )         perror( " sigaddset " );      /*  Mask SIGQUIT  */      if  (sigprocmask(SIG_SETMASK,  & new & old)  <   0 )     {         perror( " sigprocmask " );         exit( 1 );     }     printf( " SIGQUIT is blocked " );     printf( " Now try Ctrl /  " );     sleep( 5 );  /*  SIGQUIT will pending  */      /*  Get pending  */      if  (sigpending( & pend)  <   0 )         perror( " sigpending " );      if  (sigismember( & pend, SIGQUIT))         printf( " SIGQUIT pending " );      /*  Restore signal mask  */      if  (sigprocmask(SIG_SETMASK,  & old, NULL)  <   0 )     {         perror( " sigprocmask " );         exit( 1 );     }     printf( " SIGQUIT unblocked " );     printf( " Now try Ctrl /  " );     sleep( 5 );      return   0 ; }

这个程序在开始的时候用sigprocmask屏蔽了SIGQUIT(ctrl+/触发), 在5秒内触发的该信号将可以从sigpending中获得; 然后程序把SIGQUIT解除屏蔽(恢复以前的屏蔽字), 此时再触发该信号将调用sig_quit信号处理函数.

From:http://blog.csdn.net/dai_weitao/archive/2007/09/25/1800156.aspx

你可能感兴趣的:(多线程,linux,null,Signal,网易)