【发布时间】:2012-08-30 09:15:10
【问题描述】:
如何在 Linux 操作系统中检测父进程死亡?
如果父进程名为fork(),则创建子进程。在父进程中,我可以使用系统调用wait() 等待终止的子进程,并获取其状态。
但是,我找不到有关子进程如何检测父进程死亡的信息?
【问题讨论】:
如何在 Linux 操作系统中检测父进程死亡?
如果父进程名为fork(),则创建子进程。在父进程中,我可以使用系统调用wait() 等待终止的子进程,并获取其状态。
但是,我找不到有关子进程如何检测父进程死亡的信息?
【问题讨论】:
您可以通过调用getppid() 获取父进程ID,然后通过kill() 发送信号0。返回码 0 表示该进程仍处于活动状态。
正如@Ariel 所提到的,getppid() 将返回原始父进程的 pid 或 init 的 pid,即 pid 1。因此,您必须在启动时或稍后调用 getppid() 来存储父进程 pid检查你的父母是否有 pid 1。
根据 Linux 上的this answer,您还可以通过prctl() 的PR_SET_PDEATHSIG 选项和自选信号检测父母的死亡。
【讨论】:
kill 永远不会为来自getppid 的pid 返回0)。如果进程的父进程死亡,它通常会杀死子进程。如果不是,那么该进程将被具有 pid 1 的 init 采用 - 所以检查一下。
kill - 只需再次调用 getppid 并查看它是否发生了变化(尽管那里存在潜在的竞争条件,所以还要检查 1)。
如果父进程和子进程的生命周期都在您的控制之下,最便携的方法是与父进程共享管道或套接字的一半。
这种方法的优点是它完全避免了信号,这是 UNIX 中最难掌握的机制之一,并提供了一个可以轻松与网络多路复用器或 GUI 事件循环集成的可等待描述符。
【讨论】:
在我的 Ubuntu 16.04.1 LTS 中,getppid() 在父级杀死后不返回“1”但进程的 id 为“/sbin/upstart --user”,因此检查 getppid() == 1 将不起作用并且 getppid()应在子项启动时保存并稍后进行比较。
【讨论】: