什么是“子收割者”过程?

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会。

实施此机制的原因是用户空间服务管理器/主管(如upstartsystemd)需要跟踪他们启动的服务。许多服务通过双分叉进行守护进程并隐式地重新父级为 PID 1。服务管理器将不再能够SIGCHLD为它们接收信号,并且不再负责使用wait(). 在 PID 1 清理重新创建父进程的那一刻,所有关于子进程的信息都将丢失。现在,服务管理器进程可以将自己标记为一种“sub-init”,并且现在能够作为由启动的服务创建的所有孤立进程的父进程。所有SIGCHLD信号都将传递给服务管理器。

在 Linux 中,守护进程通常是通过fork两次创建的,中间进程在 fork 孙子进程后退出。这是避免僵尸进程的常用技术。init 脚本调用一个孩子。那个孩子再次分叉,因此立即退出。孙子将被 收养init,它会不断调用wait()收集其子孙的退出状态以避免僵尸。有了子收割者的概念,用户空间服务管理器现在变成了新的父级,而不是init.

  • 按照上面的 [Linux 内核 3.4](http://kernelnewbies.org/Linux_3.4#head-669b0cddccfb9794868a04b2bccdc2bbf9bc0f9e) 链接,[提交评论](https://git.kernel.org/cgit/linux/kernel/git /torvalds/linux.git/commit/?id=ebec18a6d3aa1e7d84aab16225e87fd25170ec2b) 有更多细节。(对隐藏在 git 评论中的细节感到敬畏) (3认同)