我看到一些SIGCHLD处理程序的例子,如:
void child()
{
wait(0);
signal(SIGCHLD, child);
}
void server_main()
{
...
signal(SIGCHLD, child);
...
for(;;;) {
...
switch(fork()) {
...
}
}
处理程序中有两个部分让我困惑: 1)。当孩子终止或停止时,会捕获SIGCHLD。那为什么需要在处理程序内调用wait?信号已经到来。 2)。为什么需要重新安装SIGCHLD处理程序。是不是信号调用会一劳永逸地安装处理程序?
谢谢!
答案 0 :(得分:2)
wait()
将清除进程表
来自那个孩子的过程。n
子进程,那么当所有n
个子进程都死亡时,没有理由让信号处理程序仍然存在。 我建议您查看sigaction
,因为signal
的行为因Unix而异。
答案 1 :(得分:1)
信号调用是否会一劳永逸地安装处理程序?
你不能依赖这种行为;也许信号处理程序将被清除,也许它会持续存在。这是历史信号处理问题的一部分。我系统上的signal(3)
联机帮助页报告:
When a signal occurs, and func points to a function, it is
implementation-defined whether the equivalent of a:
signal(sig, SIG_DFL);
is executed or the implementation prevents some
implementation-defined set of signals (at least including
sig) from occurring until the current signal handling has
completed.
不可靠的信号几乎被基于sigaction(2)
的信号所取代,这些信号在SysVr4中引入并在POSIX.1-2001中标准化:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
编写这些内容可能更复杂,但是一旦编写完代码,您就不必怀疑是否需要重新安装处理程序 - 而且您不必担心信号会在处理信号时第二次到达。