技术开发 频道

Linux编程:信号篇

第2节 POSIX信号

    POSIX signal API提供了一种新的机制,它能够处理多个信号而不必中断当前进程。

    对于POSIX的信号实现来说,当一个进程正在处理一个信号时,如果有其他的信号到达,那末这些“其他的”信号将被挂起,直到该handler返回为止。可是,当一个SIGx信号在挂起之际,如果又发来另一个SIGx信号,那么内核仅把一个信号递送给该进程——也就是说,有一个信号丢失了。实际上这算不上是个大问题,因为信号除了信号号码本身之外不传送任何的信息。因此,在一个非常短的周期内多次发送一个信号相当于只将它发送一次。

信号集

    POSIX signal函数(在<signal.h>中)运行在用sigset_t数据类型封装的信号集之上。这里是他们的原型和说明∶

int sigemptyset(sigset_t * pset); -- 将pset中的信号全部清除

int sigfillset(sigset_t * pset); -- 将全部有效的信号填入pset

int sigaddset(sigset_t * pset, int signum); -- 将信号signum添加到pset

int sigdelset(sigset_t * pset, int signum); -- 从pset中删除信号signum。

int sigismember(const sigset_t * pset, int signum); -- 如果signum属于pset,返回一个非零值;否则为0。

记录Handler

    为记录handler,需要调用sigaction()函数,原型如下∶

int sigaction(int signum, struct sigaction * act, struct sigaction * prev);

    sigaction ()的作用是为信号signum设置handler。内核对signum的处理将在参数act中加以描述,sigaction类型如下:

struct sigaction {
sighanlder_t sa_hanlder; sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); /*从来不用* /};

    sa_hanlder是一个指针,它指向以下类型的函数∶

void handler (int signum);

    另外,它还有两个特值:SIG_DFL和SIG_IGN。sa_mask域包含了所有当handler运行时内核将阻塞的信号。注意,不管sa_mask的值为何,正在被处理的信号总是被阻塞。当然,通过适当设定sa_flags域的flags,你还是可以逾越这个特性的。通过逐位或运算,这些flags可以取下列一个或多个值:

1.SA_NOCLDSTOP - -确保父进程当它的一个子进程停止时不会收到一个SIGCHLD信号。
2.SA_NOMASK - -逾越该信号的默认阻塞,如果它的handler当前正在执行的话。这些flag能模拟ANSI的不可靠的信号。
3.SA_ONESHOT -重新设置signum的handler为SIG_DFL。这些flag模拟ANSI signal ()函数的行为
4.SA_RESTART - -当handler退出时,确保syscall重新启动。

    如果sigactions的最后的参数不是NULL,在sigaction ()被调用之前用signum的序列填入。为了能够获得当前的信号序列而不改变它,应该把NULL作为第二个参数传递,然后将正确的sigaction指针作为第三个参数传递。

0
相关文章