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