【问题标题】:Handling SIGCHLD, how to record the return values of children as they die处理 SIGCHLD,如何记录孩子死亡时的返回值
【发布时间】:2011-07-28 16:53:38
【问题描述】:
void childSignalHandler(int signo) {
    int status;

    pid_t pid = wait(&status);

    struct PIDList* record = getRecordForPID(childlist, pid);
    if (record != NULL)
        record->returnValue = status;
}

快速提问:

我希望这个处理程序在一个孩子死去(这个应用程序产生很多孩子)时,获取他们的返回值并记录下来(最后三行)。会这样做吗,还是我把所有这些 API 业务都弄错了?

感谢您的宝贵时间!

(另外,Linux API 术语令人毛骨悚然,请检查垂死的孩子之类的)

【问题讨论】:

    标签: c linux unix signals low-level


    【解决方案1】:

    如果您将函数设置为SIGCHLD 的处理程序,这应该可以完成工作。

    但是,SIGCHLD 可以在子进程退出后发送到父进程不仅。其他一些事件也以这种方式发出信号(例如当孩子停止时)。详细解释见man wait(3)

    【讨论】:

      【解决方案2】:

      音符信号没有排队。如果两个孩子相继死去,您可能只收到一个SIGCHLD。因此,您实际上应该循环调用waitpid(),直到没有更多退出进程需要处理:

      int status;
      pid_t pid;
      
      while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
          if (WIFEXITED(status)) {
              struct PIDList *record = getRecordForPID(childlist, pid);
      
              if (record != NULL)
                  record->returnValue = WEXITSTATUS(status);
          }
      }
      

      【讨论】:

      • 请注意,在现代系统上,SIGCHLD 已排队,但问题中的代码仍然是错误的,因为不能保证wait() 将返回当前SIGCHLD 实例的pid为了。当wait()或类似函数报告子进程的状态时,对应的SIGCHLD信号(如果有)被认为是接受的,不会调用信号处理程序。
      • @jilles 我也观察到了这种行为:"the corresponding SIGCHLD signal, if any, is considered accepted and the signal handler will not be called"(愉快的调试时间...)。因为我不确定我的应用程序是否正常运行,所以我很高兴现在找到您对此的评论。我仍在寻找官方参考。
      • @jilles 就是这样,不是吗? If _POSIX_REALTIME_SIGNALS is defined, and the implementation queues the SIGCHLD signal, then if wait() or waitpid() returns because the status of a child process is available, any pending SIGCHLD signal associated with the process ID of the child process shall be discarded 来自linux.die.net/man/3/waitpid
      • @Jan-Philip Gehrcke 是的,就是这样。我建议使用更官方的网站,例如 www.unix.org 而不是 die.net
      猜你喜欢
      • 2015-01-20
      • 1970-01-01
      • 2018-02-22
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 2011-11-02
      相关资源
      最近更新 更多