信号之信号集

我们需要有一个能表示多个信号——信号集(signal set)的数据类型。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);
四个函数的返回值:若成功则返回0,若出错则返回-1

int sigismember(const sigset_t *set, int signo);
返回值:若真则返回1,若假则返回0,若出错则返回-1

函数sigemptyset初始化由set指向的信号集,清除其中所有信号

函数sigfillset初始化由set指向的信号集,使其包括所有信号

所有应用程序在使用信号集前,要对该信号集调用sigemptyset或sigfillset一次。这是因为C编译器将把未赋初值的外部和静态变量都初始化为0,而这是否与给定系统上信号集的实现相对应却并不清楚。

一旦初始化了一个信号集,以后就可以在该信号集中增、删特定的信号。

函数sigaddset将一个信号添加到现有集中,sigdelset则从信号集中删除一个信号。

对所有以信号集作为参数的函数,我们总是以信号集地址作为向其传送的参数

实例

如果实现的信号数目少于一个整型量所包含的位数,则可用一位代表一个信号的方法实现信号集。我们假定一种实现有31种信号和32位整型值。

sigemptyset函数将整型量设置为0,sigfillset函数则将整型量中的各个位都设置为1。

这两个函数可以在<signal.h>头文件中实现为宏:

#define    sigempty(ptr)      (*(ptr) = 0)
#define    sigfillset(ptr)    (*(ptr) = ~(sigset_t)0, 0)

注意,除了设置信号集各位为1外,sigfillset必须返回0,所以使用C语言的逗号运算符(逗号运算符是所有运算符中级别最低的),它将逗号运算符后的值作为表达式的返回值。

使用这种实现,sigaddset打开一位(将该位设置为1),sigdelset则关闭一位(将该位设置为0),sigismember测试一指定位

因为没有编号为0的信号,所以从信号编码中减去1以得到要处理位的位编码数

程序清单10-9 sigaddset、sigdelset和sigismember的实现

#include <signal.h>
#include <errno.h>

/* <signal.h> usually defines NSIG to include signal number 0 */
#define    SIGBAD(signo)    ((signo) <= 0 || (signo) >= NSIG)

int
sigaddset(sigset_t *set, int signo)
{
    if (SIGBAD(signo))
    {
        errno = EINVAL;
        return(-1);
    }
    *set |= 1 << (signo - 1);    /* turn bit on */
    return(0);
}

int 
sigdelset(sigset_t *set, int signo)
{
    if (SIGBAD(signo))
    {
        errno = EINVAL;
        return(-1);
    }
    *set &= ~(1 << (signo -1));    /* turn bit off */
    return(0);
}

int 
sigismember(const sigset_t *set, int signo)
{
    if (SIGBAD(signo))
    {
        errno = EINVAL;
        return(-1);
    }
    return(*set & (1 << (signo - 1)) != 0);
}

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

posted @ 2014-01-11 18:34  ITtecman  阅读(1145)  评论(0编辑  收藏  举报