ken*_*hew 46 process process-management linux-kernel
一些答案中使用了“subreaper”这个词。搜索谷歌也会出现“刚刚使用”这个词的条目。
我如何理解什么是“子收割者”?
cha*_*aos 56
这是作为系统调用prctl()的标志在Linux 内核 3.4中实现的。
从prctl(2)
联机帮助页:
[...] 子收割者
init(1)
为它的后代进程履行角色。当一个孤立的进程终止时(即,它的直接父进程已经终止)并被标记为具有子收割者,最近的仍然存活的祖先子收割者将收到一个SIGCHLD
信号,并能够wait(2)
在该进程上发现其终止状态。
进程可以使用 将自身定义为子收割者prctl(PR_SET_CHILD_SUBREAPER)
。如果是这样,它不是init
(PID 1) 将成为孤立子进程的父进程,而是最近标记为子收割者的活着的祖父进程将成为新的父进程。如果没有在世的祖父母,init
会。
实施此机制的原因是用户空间服务管理器/主管(如upstart
、systemd
)需要跟踪他们启动的服务。许多服务通过双分叉进行守护进程并隐式地重新父级为 PID 1。服务管理器将不再能够SIGCHLD
为它们接收信号,并且不再负责使用wait()
. 在 PID 1 清理重新创建父进程的那一刻,所有关于子进程的信息都将丢失。现在,服务管理器进程可以将自己标记为一种“sub-init”,并且现在能够作为由启动的服务创建的所有孤立进程的父进程。所有SIGCHLD
信号都将传递给服务管理器。
在 Linux 中,守护进程通常是通过fork两次创建的,中间进程在 fork 孙子进程后退出。这是避免僵尸进程的常用技术。init 脚本调用一个孩子。那个孩子再次分叉,因此立即退出。孙子将被 收养init
,它会不断调用wait()
收集其子孙的退出状态以避免僵尸。有了子收割者的概念,用户空间服务管理器现在变成了新的父级,而不是init
.