当父进程死亡时创建新的父进程

当父进程死亡时创建新的父进程

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

答案1

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

作为不锈钢说,引用之一其他在这里回答所以我不会再引用它,孤儿的父进程被设置为实现定义的过程。 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()试图通过加倍来“守护”的(相当错误的)技巧,那么一个进程将最终成为守护进程管理程序的子进程,而不是进程 #1 的子进程。当然,期望能够从登录会话中直接生成守护进程是一个根本性的错误。但这是另一个答案。

进一步阅读

答案2

根据exitThe Single UNIX® 规范第 2 版的手册页:

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

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

Linuxwait(2)手册页证实了这一点:

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

自由BSDwait(2), 网络BSDwait(2), 开放BSDwait(2)和 Mac OS Xwait(2)手册页也证实了这一点:

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

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

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

答案3

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

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

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

答案4

我不相信是这样。它总是进入 init 进程。

http://en.wikipedia.org/wiki/Orphan_process

相关内容