1.sigset_t信号集

根据信号在内核中的表示方法,每个信号的表示状态只有一个比特位,非0即1,阻塞信号集(block表)和未决信号集(pending表)可以用相同的数据类型sigset_t来存储。
sigset_t称为信号集,这个类型可以表示每个信号的"有效"或"无效"状态。
- 在阻塞信号集中"有效"和"无效"的含义是该信号是否被阻塞。
- 在未决信号集中"有效"和"无效"的含义是该信号是否处于未决状态。
阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的"屏蔽"应该理解为阻塞而不是忽略。
2.信号集操作函数
sigset_t类型对于每种信号用一个bit表示"有效"或"无效",至于这个类型内部如何存储这些bit则依赖于系统的实现 ,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。
cpp
#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);
函数解释:
- sigemptyset函数:初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
- sigfillset函数:初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。
- sigaddset函数:在set所指向的信号集中添加某种有效信号。
- sigdelset函数:在set所指向的信号集中删除某种有效信号。
- sigemptyset、sigfillset、sigaddset和sigdelset函数都是成功返回0,出错返回-1。
- sigismember函数:判断在set所指向的信号集中是否包含某种信号,若包含则返回1,不包含则返回0,调用失败返回-1。
注意:在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号处于确定的状态。
例如,我们可以按照如下方式使用这些函数。
cpp
#include <stdio.h>
#include <signal.h>
int main()
{
sigset_t s; //用户空间定义的变量
sigemptyset(&s);
sigfillset(&s);
sigaddset(&s, SIGINT);
sigdelset(&s, SIGINT);
sigismember(&s, SIGINT);
return 0;
}
注意 : 代码中定义的sigset_t类型的变量s,与我们平常定义的变量一样都是在用户空间定义的变量,所以后面我们用信号集操作函数对变量s的操作实际上只是对用户空间的变量s做了修改 ,并不会影响进程的任何行为。因此,我们还需要通过系统调用,才能将变量s的数据设置进操作系统。
引用文章: 信号的保存与阻塞