10.20 sigqueue函数
在10.8节中我们讲到许多UNIX系统并不支持信号的排队,随着POSIX.1增加了实时扩展,一些系统开始支持信号队列,在SUSv4中,信号队列功能已经从实时扩展中移到了基本规范中了。
通常来说,一个信号只能携带一个bit的信息:即是信号本身。除了排队的信号之外,这些扩展还允许应用程序在信号发送的同时传递更多的信息,这些信息被嵌入到了一个siginfo结构中,连同系统提供的信息一起,应用程序可以传递一个整数或者是一个指针来包含更多的信息给信号处理函数。
为了使用队列化的信号,我们必须按照如下步骤执行:
- 在我们使用sigaction函数安装信号处理函数的时候,我们必须指定标识SA_SIGINFO.如果我们不指定这一标识,那么信号在被发出的时候,是否被排队就是由系统实现决定的了。
- 在sigaction结构成员sa_sigaction中提供信号处理函数,而不是在通常的sa_handler数据域。
- 使用sigqueue函数来发送信号。
#include <signal.h>
int sigqueue(pid_t pid, int signo, const union sigval vaue);
Return:0 if OK, -1 on error.
sigqueue函数与函数kill相似,除了我们可以为信号指定一个发送的目标进程,并且我们可以使用参数value来传输一个整数或者是一个指针到信号处理函数。
信号不能无限地排队,在图2.9以及图2.11中我们指出的限制SIGQUEUE_MAX,当该限制被达到的时候,sigqueue就会失败,errno就会被设置为EAGAIN.
增加实时信号以后,一个独立的信号集合被引入到了应用中使用,这些信号的编号位于[SIGRTMIN,SIGRTMAX]之间(包含)。要注意的是这些信号的默认处理时终止进程。
图10.30总结了本书中提到的四个系统实现对于队列化信号的支持差异;
Behavior | SUS | FreeBSD 8.0 | Linux 3.2.0 | Mac OS X 10.6.8 | Solaris 10 |
---|---|---|---|---|---|
支持sigqueue | * | * | * | * | |
对于SIGRTMIN到SIGRTMAX之外的信号也会队列化处理 | 可选 | * | * | ||
即使调用进程没有使用标志SA_SIGINFO也会队列化信号 | 可选 | * | * |
Figure 10.30 不同平台上的队列化信号的行为
Mac OS X 10.6.8 并不支持实时信号以及sigqueue,在Solaris 10上,sigqueue位于实时库中,librt.