代码之家  ›  专栏  ›  技术社区  ›  Wizard

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

  •  0
  • Wizard  · 技术社区  · 6 年前

    我正在读关于 wait waitpid 函数,并遇到以下文本:

    当一个进程正常或异常终止时,内核通过发送一个 SIGCHLD 向父级发送信号。

    然后,家长应该处理终止。

    我很困惑 为什么 父级必须知道其子级已终止。当然,如果孩子已经被终止,它就不存在了,而且永远不会消耗任何资源。

    因为什么原因家长必须意识到这一点?

    1 回复  |  直到 6 年前
        1
  •  3
  •   paxdiablo    6 年前

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

    当子进程终止时, 几乎 完全消失。它变成了一个僵尸进程,只保留了足够的信息让另一个进程(通常是父进程)能够分辨 为什么 它终止了(基本上是返回代码)。

    然后,当父级成功执行 wait 在子级上,返回代码,并清除子级的最后一部分。

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

    sleep 3601 &
    ( sleep 3602 & )
    

    后者启动子shell,从中启动睡眠,然后子shell退出,这样子shell将 新的 起源:

    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
    

    你可以在这里看到 sleep 进程仍将shell作为父级,但另一个进程已被推到进程树上 upstart .

    通常,它被 init (a) 有专门用来收割僵尸的代码( 等待 -然后丢弃返回代码)。


    (a) 现代Unixes可以通过调用 prctl() PR_SET_CHILD_SUBREAPER 争论。这将一个过程标记为子收割器。

    然后,当一个父对象死亡时,第一个子对象在进程树上行走时成为其直接子对象的新父对象(与 初始化 成为终极收割者)。

    你可以在上面的过程树中看到,很明显 暴发户 已经做到了。那意味着 第一个收割者是在树上行走时发现的吗? 睡觉 那是属于死亡过程的,并不是一直到 初始化 .