sigset() -- sinal 的可靠对应函数

 

sigset() -- sinal 的可靠对应函数

sigset() 函数是 signal() 函数的可靠对应 函数,其声明为:
#include <signal.h>
typedef void ( * sighandler_t)( int);
sighandler_t sigset( int sig , sighandler_t disp);

sigset() 函数 sig 指定的信号部署改为 disp 指定的部署。disp 参数还可以是以下 4 个值中的一个:
  • SIG_IGN  : 忽略该信号;
  • SIG_HOLD : 将 sig 添加到进程的信号掩码;
  • SIG_DEF : 默认操作。
注意:这里的几个常量里, SIG_HOLD 特殊些,这个是 UNIX 里定义的常量。默认情况下,是不定义这个常量的。这个常量定义在 /usr/include/bits/signum.h 中:
#ifdef __USE_UNIX98
# define SIG_HOLD       ((__sighandler_t) 2)    /* Add signal to hold mask.  */
#endif
可见,需要定义宏 __USE_UNIX98 后才能直接使用到这个常量。而出现在/usr/include/features.h 头文件中的这个 __USE_UNIX98 宏默认是 #undef 的,这留给使用者自行定义。所以,为了使用这个常量,在当前目录下添加一个头文件:
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 定义为整型对象,可以作为原子实体对其进行访问,即使存在异步中断。这意味着必须使用一种机器指令访问这种类型变量,并且这种变量不可以扩展到跨越页面边界。
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值