12

如何检测 Linux 操作系统中的父进程死亡?

如果在父进程中调用fork(),则创建子进程。在父进程中,我可以使用系统调用wait()来等待终止的子进程并获取其状态。

但是,我找不到有关子进程如何检测父进程死亡的信息?

4

3 回答 3

9

getppid()您可以通过调用然后通过发送信号 0 来获取父进程 ID kill()。返回码 0 表示该进程仍处于活动状态。

正如@Ariel 所提到的,getppid()将返回原始父级的pid 或init 的pid,这将是pid 1。因此,您要么必须通过getppid()在启动时调用来存储父pid,要么稍后检查您的父级是否具有pid 1。

根据 Linux 上的这个答案,您还可以通过prctl()'sPR_SET_PDEATHSIG选项和自选信号检测父母的死亡。

于 2012-08-30T09:18:08.263 回答
5

如果父进程和子进程在其生命周期内都在您的控制之下,那么最可移植的方法是与父进程共享管道或套接字的一半。

  1. 在 fork 之前,打开一个 pipe() 或 socketpair()。
  2. 分叉后,
    1. 在父级中,关闭管道的读取端或第一个套接字。
    2. 在孩子中,关闭管道的写入端或第二个套接字。
  3. 在父级中,将剩余的文件描述符隐藏起来并忘记它。
  4. 在 child 中,使用任何多路复用的 IO 方法(select、poll 等)来测试描述符的可读性
  5. 如果描述符变得可读,则几乎可以肯定父级已死,或者某些罕见的错误导致了杂散写入,您可以通过调用 read() 来检查。如果父级真的死了, read() 将返回 0 个字节。

这种方法的优点是它完全避免了信号,这是 UNIX 中最难掌握的机制之一,并提供了一个等待描述符,可以很容易地与网络多路复用器或 GUI 事件循环集成。

于 2019-06-26T20:44:14.137 回答
3

在我的 Ubuntu 16.04.1 LTS 中,getppid() 不返回“1”,但在父级杀死后进程的 id 为“/sbin/upstart --user”,因此检查 getppid() == 1 将不起作用并且应该保存 getppid()在孩子开始和后来比较。

于 2016-12-06T13:33:45.257 回答