wblyuyang

博客园 首页 新随笔 联系 订阅 管理

屏蔽信号:
 在 sigaction 的使用中,我们已经看到了表示信号集的 sigset_t 型数据。在 Linux 上有一组函

数专门用于对信号集进行操作:
 #include <signal.h>
 int sigemptyset(sigset_t *set);
 int sigfillset(sigset_t *set);
 int sigaddset(sigset_t *set, int signum);
 int sigdelset(sigset_t *set, int signum); 
 int sigismember(const sigset_t *set, int signum);

 set 参数指向要操作的信号集,而 signum 参数则代表一个指定的信号,各个函数的作用如下:
 ◆ sigemptyset:清空信号集,返回 0 表示成功,-1 表示失败;
 ◆ sigfillset:将所有信号加入信号集,返回 0 表示成功,-1 表示失败;
 ◆ sigaddset:将指定信号加入信号集,返回 0 表示成功,-1 表示失败;
 ◆ sigdelset:将指定信号从信号集中去除,返回 0 表示成功,-1 表示失败;
 ◆ sigismember:判断一个指定的信号是否在信号集中,返回 1 表示在信号集中,0 表示不在信

号集中,-1 表示有错误发生。

 信号集在使用前需要先用 sigemptyset 或 sigfillset 函数进行初始化,然后用 sigaddset 或

sigdelset 函数增加或去除需要的信号。
 在代码中也可以直接设置或获取进程的信号掩码:
 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
 ◆ how:指定操作信号掩码的方式。
 ◆ set:指向用于设置信号掩码的信号集。
 ◆ oldset:用于返回原来的信号掩码。
 ◆ 返回值:0 表示成功,-1 表示失败。

 sigprocmask 函数将根据参数 how 指定的方式,设置当前进程的信号掩码,并把原来的信号掩码

保存在参数 oldset 指向的信号集中返回。如果 set 参数为 NULL,则不修改信号掩码;如果 oldset 参数

为 NULL,则不返回原来的信号掩码。how 有以下三个取值:
 ◆ SIG_BLOCK:将 set 参数指向信号集中的信号加入到信号掩码中。
 ◆ SIG_UNBLOCK:将 set 参数指向的信号集中的信号从信号掩码中删除。
 ◆ SIG_SETMASK:将 set 参数指向信号集设置为信号掩码。

 因此,屏蔽某个信号可以有两种方式,下面以 SIGUSR1 信号为例进行说明:
 第一种方式为使用 SIG_BLOCK 操作方式,代码如下:
 sigset_t sigset;
 sigemptyset(&sigset);
 sigaddset(&sigset, SIGUSR1);
 sigprocmask(SIG_BLOCK, &sigset, NULL); 
 
 第二种方式为使用 SIG_SETMASK 操作方式,代码如下:
 sigset_t set;
 sigprocmask(SIG_SETMASK, NULL, &set);   //先得到当前的信号掩码
 sigaddset(&set, SIGUSR1);               //将要屏蔽的信号加入
 sigprocmask(SIG_SETMASK, &set, NULL);  

 同时,要解除对信号的屏蔽,也有两种方式,仍以 SIGUSR1 信号为例:
 第一种方式,使用 SIG_UNBLOCK 操作方式:
 sigset_t sigset;
 sigemptyset(&sigset);
 sigaddset(&sigset, SIGUSR1);
 sigprocmask(SIG_UNBLOCK, &sigset, NULL);

 第二种方式,使用 SIG_SETMASK 操作方式:
 sigset_t set;
 sigprocmask(SIG_SETMASK, NULL, &set);  //先得到当前的信号掩码
 sigdelset(&set, SIGUSR1);              //将要解除屏蔽的信号去除
 sigprocmask(SIG_SETMASK, &set, NULL);

 

信号安全函数:
 如前所述,进程在收到信号并对其进行处理时,会中断当前正在执行的指令序列,而去执行信号处

理函数。但是信号的传递是异步的,系统无法确定何时传递信号给进程。如果进程在收到信号时正在执行某

个不可重入的函数,这时捕捉到信号,进程就会转而去执行信号处理函数。如果在这个信号处理函数中又再

次调用了同一个函数,就有可能产生问题。
 因此有些函数时不能在信号处理函数中调用的,那些可以在信号处理函数中调用且不会有潜在问题

的函数称为对信号安全的。下表列出了 Linux 系统中的信号安全函数,对于不在这个表中的函数,如果要

在信号处理函数中调用,则需谨慎处理。

 

posted on 2012-11-15 22:03  wblyuyang  阅读(2110)  评论(0编辑  收藏  举报