sigset() -- sinal 的可靠对应函数
sigset() 函数是 signal() 函数的可靠对应 函数,其声明为:sigset() 函数将 sig 指定的信号部署改为 disp 指定的部署。disp 参数还可以是以下 4 个值中的一个:
- SIG_IGN : 忽略该信号;
- SIG_HOLD : 将 sig 添加到进程的信号掩码;
- SIG_DEF : 默认操作。
#ifdef __USE_UNIX98 # define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */ #endif |
unix98.h
在里头添加一句:
#define __USE_UNIX98 |
测试程序:
#include <stdio.h>
#include <unistd.h>
#include "unix98.h"
#include <signal.h>
static volatile sig_atomic_t sig;
static void sigusr( int sig_num);
int main( void)
{
if ( sigset( SIGUSR1 , SIG_HOLD) == SIG_ERR)
printf( "Can't catch SIGUSR1");
if ( sigset( SIGUSR2 , sigusr) == SIG_ERR)
printf( "Can't catch SIGUSR2");
for(;;) {
pause();
if ( sig == SIGUSR1)
printf( "Received SIGUSR1 \n ");
else
printf( "Received SIGUSR2 \n ");
}
}
static void sigusr ( int sig_num)
{
if (( sig_num == SIGUSR1) || ( sig_num == SIGUSR2))
sig = sig_num;
else
printf( "Received signal %d" , sig_num);
}
编译程序时,会对 SIG_ERR 常量发出警告,因为整型量和指针型量是不匹配的。但是在 函数调用出错时,返回的是整型量(-1)。所以,对这个编译警告可以不予理会。
运行程序后,在另外一个终端里输入:
beyes@linux-beyes:~/C/signal> kill -USR1 9358
beyes@linux-beyes:~/C/signal> kill -USR2 9358
beyes@linux-beyes:~/C/signal> kill -USR2 9358
在程序运行的窗口里,可以看到,对于 SIGUSR1 信号不予理会,因为这已经被加入到了信号掩码中。而 SIGUSR2 会被捕捉到并被处理:
beyes@linux-beyes:~/C/signal> ./sigset2.exe
Received SIGUSR2
AReceived SIGUSR2
sig 变量为全局变量,被定义为 static volatile sig_atomic_t 类型。由于 sig 会被至少两个不同的控制线程访问: main() 函数和异步的信号处理程序,所以也总将 volatitle 类型限定符用于 sig 面前。
ISO C 将 sig_atomoc_t 定义为整型对象,可以作为原子实体对其进行访问,即使存在异步中断。这意味着必须使用一种机器指令访问这种类型变量,并且这种变量不可以扩展到跨越页面边界。