在Linux中,如何在退出之前了解新获得的子进程?

时间:2018-01-29 20:39:20

标签: c linux process pid

我正在编写一个调用prctl(PR_SET_CHILD_SUBREAPER, 1)的程序。因此,它可能会获得对父母退出时一无所知的流程。我希望这个过程在所有孩子都退出时退出,包括那些成为父母的孩子,因为他们本来就是孤儿。

如何以合理的方式从C或C ++程序中执行此操作?我不想一直打开/proc中的所有内容,或者打电话给我这样做的过程。无论如何,这是一个民意调查解决方案,我更倾向于一个不涉及民意调查的解决方案。

此外,让所有孩子知道他们何时打电话fork也不是一个选择。以防有人有这个好主意。

1 个答案:

答案 0 :(得分:2)

你不需要对/proc做任何奇特的事情。只需使用wait()即可。从手册页:

  

PR_SET_CHILD_SUBREAPER(自Linux 3.4开始)

     

如果arg2非零,请设置" child subreaper"调用过程的属性;如果arg2为零,则取消设置该属性。当一个   过程是      标记为子子区域,它创建的所有子项及其后代将被标记为具有   subreaper。在      效果,subreaper为其后代进程履行init(1)的角色。 终止进程时   孤儿(即      它的直接父母已经终止了并且标记为有一个subreaper,最近的仍然生活的祖先subreaper将   接收      SIGCHLD信号,能够等待(2)流程发现其终止状态。

因此,您的流程只需要在循环中调用wait,直到它返回-1并将errno设置为ECHILD。当进程树中的所有进程退出时,就会发生这种情况。只要你这样做,你就不需要知道何时获得新的子进程等待。

假设您有以下流程树,其中流程1000是收割者:

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

当您第一次调用wait时,1001和1004都需要在返回-1之前退出。现在假设1004退出:

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

在收割者中,wait返回1004.现在1001,1005和1006需要退出。接下来,1002退出:

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

收割者还没有从wait返回,因为1001仍然在运行,并且仍然可以wait为1002.此时,1002是一个僵尸。接下来,1001调用wait

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

自从1002等待1001后,收割机的预期没有变化。然后1005退出:

1000
  |---1001
  |     |---1002 (dead)
  |     |---1003
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006
收割机中的

wait返回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连续两次返回,一次返回1001并返回1003.现在收割机只等待1006.一旦退出:

1000
  |---1001 (dead)
  |     |---1002 (dead)
  |-----|---1003 (dead)
  |
  |---1004 (dead)
  |-----|---1005 (dead)
  |-----|---1006 (dead)
收割者中的

wait返回1006,下一个调用返回-1结束循环。