父进程死亡时的新父进程

use*_*503 27 process exit init

在 UNIX 中,当父进程消失时,我认为所有子进程都将 init 重置为其父进程。这不是一直正确吗?有任何例外吗?

Jde*_*eBP 75

2014 年写的三个答案,都说在 Unices 和 Linux 中,进程无一例外地被重新引导到进程#1。三个错误的答案。☺

正如SUS所说,在此处的其他答案之一中引用,因此我不会再次引用它,孤儿的父进程设置为实现定义的进程。Cristian Ciupitu 查阅 Linux 文档以了解实现定义的内容是正确的。但是他被那个文件误导了,这些文件不一致且不是最新的。

在写这三个答案的两年前,很快就到了三年前第一次写这个答案的时候,Linux 内核发生了变化。systemd 开发人员增加了进程将自己设置为“子收割者”的能力。从 Linux 3.4 开始,进程可以prctl()使用该PR_SET_CHILD_SUBREAPER选项发出系统调用,因此它们,而不是进程 #1,将成为其任何孤立后代进程的父进程。的手册页prctl()是最新的,但其他手册页尚未更新并保持一致。

在 10.2 版本中,FreeBSD 获得了相同的能力,procctl()使用PROC_REAP_ACQUIREPROC_REAP_RELEASE选项扩展了其现有的系统调用。它采用了 DragonFly BSD 的这种机制;它在 4.2 版中获得了它,最初命名reapctl()但在开发过程中重命名为procctl().

所以有一些例外,而且相当突出:在 Linux、FreeBSD/PC-BSD 和 DragonFly BSD 上,孤立子进程的父进程被设置为标记为子收割者的子进程的最近祖先进程,或进程 #1如果没有祖先子收割者进程。各种守护进程监督实用程序——包括 systemd(开发人员首先将其放入 Linux 内核的那个)、upstart 和 nosh——service-manager已经在使用它。

如果这样的守护进程的主管没有处理#1,并产生一个服务,如交互式登录会话,并在会话中的一个不通过双试图“守护进程”的(相当刚愎自用)招fork()ING,那么一个人的过程将最终成为守护进程主管的子进程,而不是进程 #1 的子进程。当然,期望能够从登录会话中直接生成守护进程是一个基本错误。但这是另一个答案。

进一步阅读


Cri*_*itu 9

根据exitThe Single UNIX® Specification, Version 2的手册页:

所有调用进程的现有子进程和僵尸进程的父进程 ID 都设置为依赖于实现的系统进程的进程 ID。也就是说,这些进程由一个特殊的系统进程继承。

对于大多数 Unix 变体,该特殊进程是init(PID 1)。

Linuxwait(2)手册页确认了这一点:

如果父进程终止,那么它的“僵尸”子进程(如果有)被 init(8) 接收,它会自动执行等待以移除僵尸。

FreeBSD wait(2)、 NetBSD wait(2)、 OpenBSDwait(2)和 Mac OS Xwait(2)手册页也证实了这一点:

如果父进程在没有等待其所有子进程终止的情况下终止,则剩余的子进程将被分配父进程 1 ID(init 进程 ID)。

Oracle Solaris 11.1wait(3C)手册页也证实了这一点:

如果父进程不等待子进程终止就终止,则每个子进程的父进程ID设置为1,初始化进程继承子进程;见Intro(2)


Sim*_*_Me 4

将我的评论移至答案......我不相信有例外。

发现“有时父进程会在其子进程被杀死之前被杀死。在这种情况下,“所有进程的父进程”init进程将成为新的 PPID(父进程 ID)。有时这些进程被称为孤儿进程。” 来源

IBM 的博客中也有类似的描述:“父进程在子进程之前死亡或被杀死。在上述场景中,子进程成为孤儿进程(因为它失去了父进程)。在 Linux 中,该init进程来拯救孤儿进程并收养它们。这意味着子进程失去其父进程后,该init进程将成为其新的父进程。”