如何从C程序中检查分支进程是否仍在运行

6

我有一个分叉进程的pid。现在,从我的c代码(在Linux上运行)中,我必须定期检查这个进程是否仍在运行或已终止。我不想使用像wait()waitpid()这样的阻塞调用。需要(最好是)一个非阻塞系统调用,它只会检查此pid是否仍在运行并返回子进程的状态。

最佳和最简单的方法是什么?


2
https://dev59.com/y2ox5IYBdhLWcg3whUmm - 4rlekin
不,你不需要定期检查。如果你没有收到SIGCHLD信号,那么进程仍在运行。只有在收到SIGCHLD信号时才需要检查子进程。 - William Pursell
3个回答

14
waitpid()函数可以使用选项值WNOHANG来避免阻塞。请参见手册页,像往常一样。
即便如此,我也不确定进程ID是否有系统保证不会被回收,这可能会导致竞争条件的出现。

8
waitpid 只能用于调用它的进程的子进程,而且它们的 pid 只有在被等待后才能被回收,因此这是检查子进程是否已终止的正确方法。 - Art
不预先存储子进程的PID,此解决方案仅返回已终止的子进程PID。要获取正在运行的子进程PID,我该怎么做?示例代码链接https://paste.ubuntu.com/25386744/ - alhelal

5
kill(pid, 0);

如果PID存在,这将“成功”(返回0)。当然,它可能存在,因为原始进程已经结束并且有新的进程取代了它...你需要决定这是否重要。你可以考虑注册一个SIGCHLD处理程序,这不依赖于可能被回收的PID。

3
如果进程死亡/退出并且另一个进程使用相同的pid启动,则此方法也将成功。这是一个非常糟糕的做法,不应该得到鼓励。 - Art
@Art:我在我的答案中明确承认了这一点,并提供了一个更好的解决方案,第二次明确提到了它如何更好。说我“鼓励”这种有争议的方式有点过分了,你不觉得吗? - John Zwinck
1
请注意,如果您正在测试自己的子进程,则此方法是安全的,因为子进程在等待后才会回收pid,但这仍然是一种不良实践,因为更好的系统调用存在于此,并且最终某人将错误地使用此方法并获得错误结果。除了对waitpid的调用之外,几乎所有使用pid的情况都可能存在潜在危险的竞态条件。 - Art

3

waitpid() 中使用 WNOHANG 选项。


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