Science for all





信号

信号

信号是类Unix操作系统世界里“中断”的一种简单形式,而且是Unix中古老的一部分。进程可以对另一个进程设置“信号”(即使用kill(1)或kill(2)),这样其它的进程就会异步地接收到信号并进行处理。进程要拥有向某些其它进程发送信号的许可必须具有root权限,或者发送进程的真实或有效用户ID等于接收进程的真实或保存的set-user-ID。

虽然信号是Unix中古老的一部分,但在不同的实现下语义有所不同。从根本上说,它们涉及到“在处理一个信号时出现另一个信号会发生什么?”一类的问题。较早的Linux libc 5对某些信号操作使用一组与新的GNU libc库不同的语义。要了解更多信息,请参考glibc的FAQ(在某些系统中可以在/usr/doc/glibc-*/FAQ找到其本地拷贝)。

对于新程序,应该只使用POSIX信号系统(这依然是基于BSD上的工作);它受到广泛的支持,而且不会有某些早期信号系统具有的问题。POSIX信号系统是基于使用数据类型sigset_t,它可以通过一组操作来处理:sigemptyset()、sigfillset()、sigaddset()、sigdelset()和sigismember()。可以从sigsetops(3)中读到这些信息。然后用sigaction(2)、sigaction(2)、sigprocmask(2)、sigpending(2)和sigsuspend(2)来建立一个处理信号的程序(参见相应的man帮助页以了解更多信息)。

一般应该使信号处理程序很小而且简单,同时小心对待竞争状态。由于信号天生就是异步的,所以很容易导致竞争状态。

对于服务器程序有一个通用约定:如果接收到SIGHUP,应该关闭所有日志文件、重新打开并读入配置文件,然后重新打开日志文件。这样就支持服务器不暂停地完成重新配置,以及无数据丢失的日志轮转。如果要编写的服务器程序可以使用该约定,请支持这一约定。