父流程死亡时的新父流程


22

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

Answers:


5

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

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

IBM 博客中也描述了类似的情况:“父进程在子进程之前死亡或被杀死。在上述情况下,子进程成为孤立进程(因为它失去了其父init进程)。在Linux中,该进程用于挽救父进程。孤儿程序并采用它们。这意味着在孩子失去其父级之后,该init过程将成为其新的父级过程。”


61

2014年写的三个答案都说,在Unices和Linux中,该流程无一例外地被复制为#1。三个错误答案。☺

就像SUS所说的那样,在这里用其他答案中的一个引用,这样我就不再引用它了。孤儿的父进程设置为实现定义的进程。Cristian Ciupitu有权查阅Linux文档来查看实现定义。但是他被这份文件所误导,这是不一致的并且不是最新的。

在编写这三个答案的两年前,直到三年前第一次编写此答案时,Linux内核发生了变化。系统化的开发人员增加了流程将自己设置为“次级收货人”的能力。从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内核的程序),暴发户和nosh service-manager)已经利用了这一功能。

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

进一步阅读


我实际上已经注意到孤立进程已附加到会话init(在具有Upstart的Ubuntu上),但从未意识到它的重要性。+1
大师

请参阅unix.stackexchange.com/a/194208/5132,详细了解新贵会话初始化。
JdeBP

8

根据exitThe SingleUNIX®Specification版本2 的手册页:

所有调用进程的现有子进程和僵尸进程的父进程ID都设置为与实现相关的系统进程的进程ID。即,这些过程是由特殊系统过程继承的。

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

Linux wait(2)手册页对此进行了确认:

如果父进程终止,则init(8)将采用其“僵尸”子级(如果有的话),它将自动执行等待以删除僵尸。

FreeBSD wait(2),NetBSD wait(2),OpenBSD wait(2)和Mac OS X wait(2)手册页也对此进行了确认:

如果父进程在不等待其所有子进程终止的情况下终止,则将为其余子进程分配父进程1 ID(初始化进程ID)。

Oracle Solaris 11.1 wait(3C)手册页也对此进行了确认:

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.