在 Linux 中,您如何在新获取的 child 进程退出之前了解它们?

In Linux, how do you learn about newly acquired child processes before they exit?

我正在编写一个调用 prctl(PR_SET_CHILD_SUBREAPER, 1) 的程序。因此,它可能会获取对其 parent 何时退出一无所知的进程。我希望这个进程在所有 children 退出时退出,包括它成为 parent 的进程,否则它们将成为孤儿。

如何从 C 或 C++ 程序以合理的方式执行此操作?我不想一直打开 /proc 中的所有内容,也不想调用为我执行此操作的流程。无论如何,这是一个轮询解决方案,我更喜欢不涉及轮询的解决方案。

此外,跟踪所有 children 以找出他们何时调用 fork 也不是真正的选择。以防万一有人有那个好主意。

您不需要对 /proc 做任何花哨的事情。只需使用 wait()。来自手册页:

PR_SET_CHILD_SUBREAPER (since Linux 3.4)

If arg2 is nonzero, set the "child subreaper" attribute of the calling process; if arg2 is zero, unset the attribute. When a process is marked as a child subreaper, all of the children that it creates, and their descendants, will be marked as having a subreaper. In effect, a subreaper fulfills the role of init(1) for its descendant processes. Upon termination of a process that is orphaned (i.e., its immediate parent has already terminated) and marked as having a subreaper, the nearest still living ancestor subreaper will receive a SIGCHLD signal and be able to wait(2) on the process to discover its termination status.

所以你的进程只需要坐在一个循环中调用 wait 直到它 returns -1 并且 errno 被设置为 ECHILD。这将在进程树中的 all 个进程退出时发生。只要你这样做,你就不需要知道什么时候获取新的子进程等待。

假设您有以下进程树,进程 1000 是收割者:

1000
  |---1001
  |     |---1002
  |     |---1003
  |
  |---1004
        |---1005
        |---1006

第一次调用wait时,1001和1004都需要先退出returns -1。现在假设 1004 退出:

1000
  |---1001
  |     |---1002
  |     |---1003
  |
  |---1004 (dead)
  |-----|---1005
  |-----|---1006

死神中,wait returns 1004,现在1001、1005、1006需要退出。接下来,1002退出:

1000
  |---1001
  |     |---1002 (zombie)
  |     |---1003
  |
  |---1004 (dead)
  |-----|---1005
  |-----|---1006

收割者还没有从waitreturn,因为1001仍然运行并且仍然可以wait给1002。在这一点上,1002是僵尸.接下来,1001 调用 wait:

1000
  |---1001
  |     |---1002 (dead)
  |     |---1003
  |
  |---1004 (dead)
  |-----|---1005
  |-----|---1006

收割者的预期没有变化,因为 1001 等待 1002。然后 1005 退出:

1000
  |---1001
  |     |---1002 (dead)
  |     |---1003
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006

wait 在死神 return 的 1005 中,现在需要 1001 和 1006 才能退出。然后1003退出:

1000
  |---1001
  |     |---1002 (dead)
  |     |---1003 (zombie)
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006

同样,收割者的期望没有改变。现在1001退出:

1000
  |---1001 (dead)
  |     |---1002 (dead)
  |-----|---1003 (dead)
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006

现在 wait 在收割者 return 中连续两次,一次 returning 1001 一次 returning 1003。现在收割者只等待1006.一旦退出:

1000
  |---1001 (dead)
  |     |---1002 (dead)
  |-----|---1003 (dead)
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006 (dead)

wait在死神returns 1006,下一次调用returns -1结束循环。