重新安装SIGCHLD处理程序



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

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

处理程序中有两个部分让我感到困惑:1). SIGCHLD在子进程终止或停止时被捕获。那么为什么需要在处理程序中调用wait呢?信号已经到了。2).为什么需要重新安装SIGCHLD处理器。是不是信号调用将一劳永逸地安装处理程序?

谢谢!

  1. SIGCHLD将在子进程完成时触发执行。然而,它仍将在进程表中(作为所谓的僵尸进程),以便让父进程取回退出孩子的价值。调用wait()将清除进程表
  2. 如果你只创建n子进程,那么当所有n子进程死亡时,信号处理程序仍然存在是没有理由的。

我建议你看看sigaction,因为signal的行为在不同的unix中是不同的。

是不是信号调用将一劳永逸地安装处理器?

你不能依赖这个行为;也许信号处理程序将被清除,也许它将持续存在。这是历史信号处理问题的一部分。我的系统上的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.

不可靠信号几乎被SysVr4中引入的基于sigaction(2)的信号所取代,并在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);
令人遗憾的是,这些代码编写起来更复杂,但是一旦您编写了代码,您就不必担心是否需要重新安装处理程序——并且您不必担心在处理信号时信号会第二次到达。

相关内容

最新更新