如何检查带有pid X的进程是否是一个僵尸?

时间:2009-10-24 20:35:41

标签: c process posix

我得到了一个进程的PID,我需要在C中使用POSIX系统调用检查它是否是一个僵尸。我应该怎么做?

我遇到的问题是我有一个过程并且它分叉给许多孩子,孩子们都做了高管,有时我想在后台做exec所以我不能等待()那些去的孩子在背景中。我可以定期等待(一次在我的主循环中),但我需要知道哪些进程是僵尸,所以我的父进程在等待不会很快结束的孩子时不会挂起。

如果你很好奇,我正在构建一个unix shell,它的shell属性让子进程异步表现。

5 个答案:

答案 0 :(得分:5)

您无法检查进程是否是纯POSIX调用的僵尸 - 除非您是父进程,并通过wait family调用获取它。所以你必须找个好地方等孩子。

一种选择是设置SIGCHLD处理程序并在那里执行waitpid(0, &status, WNOHANG)。一定要循环,直到它不再找到任何进程 - 如果两个孩子在短时间内死亡,你可能只得到一个SIGCHLD

另一个选择是双叉 - 即fork(),让孩子(称之为孩子A)再次分叉,让第二个孩子(孩子B)执行。然后孩子A立即退出。同时父母对孩子A wait()。一旦孩子A离开,系统的初始化过程将在孩子B最终死亡时负责收割。这种方法比较简单,但是你的shell无法知道子B何时死亡,所以如果你需要这些信息,请使用前一种方法。

答案 1 :(得分:3)

但是......但是......僵尸是一个孩子(在某种程度上)并且正在检查的过程是父母,对吗?因此,如果您担心某个特定的pid是僵尸,为什么不只用waitpid(2) WNOHANG并摆脱它?现在,这将消耗退出状态,因此如果某个其他流程可能希望将来真正wait,那么这可能是一个坏主意。

答案 2 :(得分:1)

你提到你正在构建一个Unix shell;你应该读这个:Proper handling of SIGINT/SIGQUIT

答案 3 :(得分:1)

通常情况下,shell会在打印其提示之前不久检查已解散的子项 - 使用waitpid(2)系统调用和已经讨论过的WNOHANG选项。您可能还需要一个SIGCHLD处理程序 - 但是如果您正忙着等待某个前台进程终止并且它实际上是一个终止的后台进程,那么您必须决定要对该信息做什么。

这只是当前所选答案的一个小变化。

答案 4 :(得分:0)

那么shell命令'ps'会显示活动进程表,你可以在其中发现进程“已经不存在”?我想必须有办法从c代码中获取这些信息。