进程可以将其子进程的所有权传递给其父进程吗?
背景
假设我们有 3 个进程:祖父母、父母和孩子。
父母生成孩子并继续生存(父母不会死亡)。
祖父母在孩子死亡时进行处理,因此需要在孩子死亡时通知祖父母。获得 SIGCHLD 会非常好。
答案1
一般来说,父进程负责wait()
对其子进程执行操作,以便子进程在终止时不会变成僵尸进程。如果父进程在子进程之前终止,那么必须有某个进程来扮演父进程的清理角色,再次防止子进程成为僵尸进程。默认情况下,当进程终止时,任何剩余的子进程都将重新设置为 pid 1 的进程。
Linux 确实prctl
为系统调用提供了该PR_SET_CHILD_SUBREAPER
选项。根据手册页prctl
:
PR_SET_CHILD_SUBREAPER
(从 Linux 3.4 开始)如果
arg2
非零,则设置调用进程的“child subreaper”属性;如果arg2
为零,则取消设置该属性。
init(1)
子收割者履行其后代进程的角色。当一个进程成为孤立进程(即,它的直接父进程终止)时,该进程将被重新指定为最近的仍然存在的祖先子收割者。随后,对孤立进程的调用
getppid()
现在将返回子收割器进程的 PID,并且当孤儿进程终止时,子收割器进程将收到信号SIGCHLD
,并且能够wait(2)
在进程上发现其终止状态。“child subreaper”属性的设置不会被
fork(2)
和创建的子级继承clone(2)
。该设置将在整个过程中保留execve(2)
。建立子收割器进程在会话管理框架中非常有用,其中进程的分层组由子收割器进程管理,当其中一个进程(例如,双分叉守护进程)终止时,需要通知子收割器进程(也许以便它可以重新启动)那个过程)。出于类似的原因,某些
init(1)
框架(例如systemd(1)
)采用了 subreaper 进程。
这可能是一种选择,但是父母去世的传递后代(不仅仅是孙子)将被重新指定为调用进程的父级。