信号集

信号集

信号集函数

  Linux使用数据结构sigset_t来表示一组信号。其定义如下:

#include <bits/sigset.h>

/* A `sigset_t' has a bit for each signal. */

# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
typedef struct
{
    unsigned long int __val[_SIGSET_NWORDS];
} __sigset_t;

  由该定义可见,sigset_t实际上是一个长整型数组,数组的每个元素的每个位表示一个信号。这种定义方式和文件描述符集fd_set类似。Linux提供了如下一组函数来设置、修改、删除和查询信号集:

#include <signal.h>
/* 清空信号集 */
int sigemptyset(sigset_t *set);
/* 在信号集中设置所有信号 */
int sigfillset(sigset_t *set);
/* 将信号signum添加至信号集中 */
int sigaddset(sigset_t *set, int signum);
/* 将信号signum从信号集中删除 */
int sigdelset(sigset_t *set, int signum);
/* 测试signum是否在信号集中 */
int sigismember(const sigset_t *set, int signum);

进程信号掩码

  我们可以利用sigaction结构体的sa_mask成员来设置进程的信号掩码。此外,如下函数也可以用于设置或查看进程的信号掩码:

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

  set参数指定新的信号掩码,oldset参数则输出原来的信号掩码(如果不为NULL的话)。如果set参数不为NULL,则how参数指定设置进程信号掩码的方式,其可选值如下:

how参数 含义
SIG_BLOCK 新的进程信号掩码是其当前值和set指定信号集的并集
SIG_UNBLOCK 新的进程信号掩码是其当前值和~set信号集的交集,这种情况和第一种相反
SIG_SETMASK 直接将进程信号掩码设置为set/td>

  如果set为NULL,则进程信号掩码不变,此时我们仍然可以利用oldset参数来获取进程当前的信号掩码。

  sigprocmask成功时返回0,失败则返回-1并设置errno。

被挂起的信号

  设置进程信号掩码后,被屏蔽的信号将不能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果我们取消对被挂起信号的屏蔽,则它能立即被进程接收到。如下函数可以获得进程当前被挂起的信号集:

#include <signal.h>
int sigpending(sigset_t *set);

  set参数用于保存被挂起的信号集。显然,进程即使多次接收到同一个被挂起的信号,sigpending函数也只能反映一次。并且,当我们再次使用sigprocmask使能该挂起的信号时,该信号的处理函数也只被触发一次。

  sigpending成功时返回0,失败时返回-1并设置errno。

你可能感兴趣的:(信号集)