在C语言中的Linux编程中,一个子进程是否能等待父进程终止?

6
在Linux的C编程中,我知道wait()函数用于等待子进程终止,但是是否有一些方法(或函数)让子进程等待父进程终止呢?

2
创建父进程和子进程之间的管道。当父进程终止时,子进程将从管道中读取EOF。 - Barmar
4个回答

10

Linux有一个扩展功能(非POSIX函数)可实现此功能。查找 prctl ("进程相关控制")。

使用prctl,您可以安排子进程在父进程终止时接收信号。查找使用prctlPR_SET_PDEATHSIG 操作码。

例如,如果将其设置为SIGKILL信号,则有效地为我们提供了一种方法,使得子进程在父进程终止时也终止。当然,该信号可以是子进程可以捕获的任何信号。

prctl还可以执行各种其他任务。它就像一个以进程本身作为目标的 ioctl:一个“进程 ioctl”。


还要注意,您可以使用 signalfd 通过文件描述符同步获取信号(例如,通过 select 进行监视),而不是通过处理程序异步获取信号(这样只允许非常少的安全操作)。 - o11c
太好了,谢谢!我最终发现了一个竞态条件,这个 unshare 问题 解释得很清楚(并提供了修复方法)。 - David
@David 我认为这篇文章把问题复杂化了。简单来说,当你的进程准备好捕获信号时,调用 prctl 函数,这样就不会在进程启动早期等不方便的时间发生信号。然后,在调用函数后,检查父进程是否仍然存活。如果你确定你的程序不是由 init 守护进程(PID 1)直接生成的,你可以调用 getppid 函数;如果返回值为 1,则表示父进程已经死亡(导致该进程被重新分配给 PID 1 作为其父进程)。 - Kaz
@Kaz 我认为你不能真正检查父进程ID是否为1,因为在进程层次结构中可能会注册一个子收割者成为孤儿进程的父进程(其PID!= 1)。而且我怀疑仅仅检查父进程PID是否已更改在一般情况下也不正确。或者至少我不会相信它能够在一般情况下工作。 - David

4

简短回答:不行。

父进程可以控制其子进程的终端或进程组,这就是为什么我们有wait()waitpid()函数。子进程不能控制其父进程,因此没有内置方法实现。

如果你真的需要子进程知道其父进程何时退出,你可以让父进程在atexit()处理程序中向子进程发送信号,并让子进程捕获该信号。


2
在Linux中,您可以使用带有值PR_SET_PDEATHSIG的prctl来建立一个信号,当创建该进程的线程死亡时,该信号将被发送到您的进程。也许您会发现它很有用。

1
当父进程结束时,子进程由init接管,因此在子进程中检查ppid()==1或ppid()!=oryginal PPID就足够了。这意味着父进程已经完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接