在10.8节中,我们介绍了大部分UNIX系统不对信号排队。在POSIX.1的实时扩展中,有些系统开始增加对信号排队的支持。在SUSv4中,排队信号功能已从实时扩展部分移至基础说明部分。
通常一个信号带有一个位信息:信号本身。除了对信号排队以外,这些扩展允许应用程序在递交信号时传递更多的信息(回忆10.14节)。这些信息嵌入在siginfo
结构中。除了系统提供的信息,应用程序还可以向信号处理程序传递整数或者指向包含更多信息的缓冲区指针。
使用排队信号必须做以下几个操作。
- 使用
sigaction
函数安装信号处理程序时指定SA_SIGINFO
标志。如果没有给出这个标志,信号会延迟,但信号是否进入队列要取决于具体实现。 - 在
sigaction
结构的sa_sigaction
成员中(而不是通常的sa_handler
字段)提供信号处理程序。实现可能允许用户使用sa_handler
字段,但不能获取sigqueue
函数发送出来的额外信息。 - 使用
sigqueue
函数发送信号。
#include <signal.h>
int sigqueue(pid_t pid, int signo, const union sigvalvalue);
//返回值:若成功,返回0;若出错,返回−1
sigqueue
函数只能把信号发送给单个进程,可以使用value
参数向信号处理程序传递整数和指针值,除此之外,sigqueue
函数与kill
函数类似。
信号不能被无限排队。回忆图2-9和图2-11中的SIGQUEUE_MAX
限制。到达相应的限制以后,sigqueue
就会失败,将errno
设为EAGAIN
。
随着实时信号的增强,引入了用于应用程序的独立信号集。这些信号的编号在SIGRTMIN
~SIGRTMAX
之间,包括这两个限制值。注意,这些信号的默认行为是终止进程。
图10-30总结了排队信号在本书不同的实现中的行为上的差异。
Mac OS X 10.6.8并不支持
sigqueue
或者实时信号。在Solaris 10中,sigqueue
在实时库librt中。
图10-30 不同平台上排队信号的行为