【问题标题】:SIGCHLD handler reinstallSIGCHLD 处理程序重新安装
【发布时间】:2011-12-07 23:57:28
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: wait reinstall sigchld


    【解决方案1】:
    1. SIGCHLD 将在子进程完成时触发 执行。然而,它仍会在进程表中(作为 所谓的僵尸进程)为了让父进程获取退出 孩子的价值。调用wait() 将清除进程表 来自那个子进程。
    2. 如果您只创建n 子进程,那么当所有n 子进程都死亡时,信号处理程序没有理由仍然存在。

    我建议您改为查看 sigaction,因为 signal 的行为因 Unix 而异。

    【讨论】:

    • 谢谢,我明白了第一点。对于第二个,为父级安装了信号处理程序,对吗?为什么当多个子进程死亡时可能导致信号处理程序不起作用?
    • 请看sarnold的解释,他解释得很好。
    【解决方案2】:

    不是信号调用会一劳永逸地安装处理程序吗?

    您不能依赖这种行为;也许信号处理程序将被清除,也许它会持续存在。这是历史信号处理问题的一部分。我系统上的 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 中引入并在 POSIX.1-2001 中标准化的基于 sigaction(2) 的信号所取代:

       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);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-07
      • 2016-10-31
      • 2019-08-04
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      • 2012-01-13
      相关资源
      最近更新 更多