c - 父进程跟踪子进程的终止状态
问题描述
我正在阅读wait
andwaitpid
函数并遇到以下文本:
当进程正常或异常终止时,内核通过向父进程发送
SIGCHLD
信号来通知父进程。然后父母应该处理终止。
我很困惑为什么父母必须知道它的孩子被终止了。当然,如果孩子已经终止,它就消失了,永远不会消耗任何资源。
为什么父母必须意识到这一点?
解决方案
如果一个进程正在启动其他进程,它通常希望跟踪它们的状态。
当子进程终止时,它几乎完全消失。它变成了一个僵尸进程,并且为另一个进程(通常是父进程)保留了足够的信息,以便能够说出它终止的原因(基本上是它的返回码)。
然后,当父级成功对子级执行 await
时,返回返回码并清理子级的最后剩余部分。
父母不必这样做。有一些方法可以启动将修改其父进程的子进程,您可以看到两者之间的区别:
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
您可以在此处看到,其中一个进程仍将我的 shell 作为父进程,sleep
但另一个进程已被推上进程树到upstart
.
通常,它被init
(a)采用,它具有专门用于收割僵尸的代码(wait
-ing 在它们上然后丢弃返回代码)。
(a)现代 UNIX 可以通过调用参数来覆盖prctl()
它PR_SET_CHILD_SUBREAPER
。这将一个进程标记为子收割机。
然后,当父节点死亡时,沿着进程树向上移动的第一个子节点成为其直接子节点的新父节点(init
最终成为最终节点)。
您实际上可以在上面的流程树中看到这一点,很明显upstart
已经做到了这一点。这意味着它是在上树时发现的第一个子收割者,因此sleep
属于死亡进程的那个没有一直上升到init
.
推荐阅读
- php - 数据表编辑,使用选择行功能删除顶部的常用按钮,而不使用编辑器数据表
- scala - DataFrame : 在 groupBy 上应用自定义函数
- c# - 非英文字符的 DateTimeOffset.TryParseExact()
- unit-testing - wrapper.find() 在单元测试中抛出错误
- python - 这个 python 脚本有什么问题?
- tensorflow - 支持 Nvidia CUDA Toolkit 9.2
- python - 使用 tf.estimator.Estimator 进行 TensorFlow 预测太慢
- php - Firebase 云消息传递 - PHP Rest API 不适用于 iOS
- c# - C# 泛型类型比较
- python - QSystemTrayIcon 使 python 崩溃