10.11 信号集
我们需要使用一种数据类型来存储多个信号,这种类型称为信号集,我们将在函数sigprocmask等函数中使用这些数据结构(下一节中),用于告知内核不要允许集合中的信号出现,正如我们早些时候提到的,不同信号的数量可能会超过一个整形变量的Bit数量,所以通常来说,我们不能使用整形变量中的每一个Bit来存储每一个信号。POSIX.1定义了数据结构sigset_t用存储信号集,并且允许如下五个函数对其进行操作:
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
All four return:0 if OK, -1 on error.
int sigismember(const sigset_t *set, int signo);
Returns:1 if true, 0 if false, -1 on error.
函数sigemptyset用于初始化set信号集,以至于其中的所有信号都将被排除。函数sigfillset用于初始化set信号集,以至于所有信号都被包含。所有应用程都应该调用在使用信号集之前调用sigemptyset或者是sigfillset一次,因为我们不能对C程序初始化外部或者静态的变量做任何假设。
一旦我们已经初始化了一个信号集,那么我们就可以增加或者删除信号集中指定的信号了,函数sigaddset用于将一个信号增加到一个信号集上,而函数sigdelset用于将一个信号从一个集合中移除,在所有将信号集作为参数的函数中,我们总是传递信号集的指针作为参数。
Implementation
如果实现所拥有的信号种类比整形变量的bit数更少,那么信号集就可能是使用整形的每一个bit来实现的,处于本节描述方便的考虑,假设某一个实现有31中不同的信号,同时整形变量有32个bit.函数sigemptyset清零整形变量,而函数sigfillset置位所有的bits,这两个函数可以在头文件
#define sigemptyset(ptr) (*(ptr) = 0)
#define sigfillset(ptr) (*(ptr) = ~(sigset_t)0, 0)
注意sigfillset函数必须返回0,因此我们使用C语言中的都好操作符来实现表达式的返回值为0.
使用这一实现,函数sigaddset将会置位一个bit,而函数sigdelset将会关闭一个bit,函数sigismember将会测试某个指定的bit.因为没有信号的数值为0,因此一个32bit变量只能存储31个信号。