SIGCHLD处理程序重新安装

时间:2011-12-07 23:57:28

标签: wait reinstall sigchld

我看到一些SIGCHLD处理程序的例子,如:

void child()                                                                                                                  
{                                                                                                                    
    wait(0);                                                                                                          
    signal(SIGCHLD, child);      
}  
void server_main()
{
    ...
    signal(SIGCHLD, child);
    ...
    for(;;;) {
        ...
        switch(fork()) {
        ...
        }
    }

处理程序中有两个部分让我困惑: 1)。当孩子终止或停止时,会捕获SIGCHLD。那为什么需要在处理程序内调用wait?信号已经到来。 2)。为什么需要重新安装SIGCHLD处理程序。是不是信号调用会一劳永逸地安装处理程序?

谢谢!

2 个答案:

答案 0 :(得分:2)

  1. 子进程完成后将触发SIGCHLD 执行。但它仍将在流程表中(作为 所谓的僵尸进程),以便让父进程获取退出 孩子的价值。调用wait()将清除进程表 来自那个孩子的过程。
  2. 如果您只创建n子进程,那么当所有n个子进程都死亡时,没有理由让信号处理程序仍然存在。
  3. 我建议您查看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);

编写这些内容可能更复杂,但是一旦编写完代码,您就不必怀疑是否需要重新安装处理程序 - 而且您不必担心信号会在处理信号时第二次到达。