父进程跟踪其子进程的终止状态

时间:2018-11-15 06:41:47

标签: c unix process

我正在阅读waitwaitpid函数,并遇到以下文本:

  

当进程正常或异常终止时,内核会通过向父进程发送SIGCHLD信号来通知父进程。

     

然后,父母应处理终止。

我对父母为什么必须知道其孩子被终止的原因感到困惑。当然,如果孩子已经终止,那么它就消失了,永远不会消耗任何资源。

出于什么原因父母必须了解它?

1 个答案:

答案 0 :(得分:3)

如果一个进程正在启动其他进程,则通常要跟踪其状态。

子进程终止时,几乎会完全消失。它变成了僵尸进程,只保留了足够的信息以供另一个进程(通常是父进程)使用,以告知为什么终止(基本上是其返回码)。

然后,当父级成功对子级执行wait时,将返回返回码,并清除子级的最后残余物。

而父母没有没有这样做。有几种方法可以启动将修改其父级的子进程,您可以看到以下两者之间的区别:

sleep 3601 &
( sleep 3602 & )

后者启动一个子外壳,然后从其中启动睡眠,然后该子外壳退出,以便该子获得一个 new 父级:

1 /sbin/init splash
|
+-- 1121 /usr/sbin/lightdm
    |
    +-- 1846 /usr/sbin/lightdm --session-child 12 19
        |
        +-- 2078 /sbin/upstart --user
        |
        +--- 29899 sleep 3602
        |
        +--- 2929 /usr/lib/gnome-terminal/gnome-terminal-server
             |
             +--- 2935 bash (my bash shell)
                  |
                  +--- 29891 sleep 3601

您可以在此处看到{em {em}}中的一个{em} 仍以我的shell作为父级,但是另一个已被推入进程树到sleep。 / p>

通常,它被upstart (a)所采用,该代码具有专门用于收割僵尸的代码(init-插入僵尸,然后扔掉返回代码)。


(a)现代UNIX可以通过使用wait参数调用prctl()来覆盖它。这会将进程标记为次要收割者。

然后,当父母死亡时,步行到流程树的第一个子收割者成为其直系子代的新父母(PR_SET_CHILD_SUBREAPER是最终收割者)。

您实际上可以在上面的过程树中看到这一点,很明显init已经做到了这一点。这意味着 it 是在树上行走时发现的第一个子收割者,因此属于死亡进程的upstart并没有一直上升到sleep