1

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

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

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

谢谢!

4

2 回答 2

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

我建议您看一下,因为Unix 之间sigaction的行为有所不同。signal

于 2011-12-08T00:00:47.887 回答
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);

遗憾的是,这些写起来更复杂,但是一旦你编写了代码,你就不必怀疑是否需要重新安装你的处理程序——而且你不必担心信号会在一秒钟内到达处理信号的时间。

于 2011-12-08T00:07:57.460 回答