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
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sigset_t 是一个用于存储信号集合的数据类型,它是一个位图,每个位代表一个信号。在使用 sigset_t 之前,需要先使用 sigemptyset 函数将其初始化为空集。 sigset_t 可以用于设置线程或进程的信号掩码,即哪些信号会被阻塞或接收。可以使用 sigaddset 和 sigdelset 函数向信号集合中添加或删除信号。sigismember 函数用于判断信号是否在信号集合中。 下面是一个简单的例子,演示了 sigset_t 的基本用法: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> int main() { sigset_t set; // 初始化为空集 sigemptyset(&set); // 添加 SIGINT 和 SIGTERM 信号 sigaddset(&set, SIGINT); sigaddset(&set, SIGTERM); // 判断 SIGINT 和 SIGKILL 是否在信号集合中 if (sigismember(&set, SIGINT)) { printf("SIGINT is in the signal set\n"); } if (sigismember(&set, SIGKILL)) { printf("SIGKILL is in the signal set\n"); } // 删除 SIGTERM 信号 sigdelset(&set, SIGTERM); // 判断 SIGTERM 是否在信号集合中 if (sigismember(&set, SIGTERM)) { printf("SIGTERM is in the signal set\n"); } else { printf("SIGTERM is not in the signal set\n"); } return 0; } ``` 在上面的例子中,我们首先使用 sigemptyset 函数sigset_t 初始化为空集。然后使用 sigaddset 函数向信号集合中添加 SIGINT 和 SIGTERM 信号,使用 sigismember 函数判断 SIGINT 和 SIGKILL 是否在信号集合中。接着使用 sigdelset 函数将 SIGTERM 信号从信号集合中删除,最后再次使用 sigismember 函数判断 SIGTERM 是否在信号集合中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值