题
我得到了一个进程的PID,我需要在C中使用POSIX系统调用检查它是否是一个僵尸。我应该怎么做?
我遇到的问题是我有一个过程并且它分叉给许多孩子,孩子们都做了高管,有时我想在后台做exec所以我不能等待()那些去的孩子在背景中。我可以定期等待(一次在我的主循环中),但我需要知道哪些进程是僵尸,所以我的父进程在等待不会很快结束的孩子时不会挂起。
如果你很好奇,我正在构建一个unix shell,它的shell属性让子进程异步表现。
解决方案
您无法检查进程是否是纯POSIX调用的僵尸 - 除非您是父进程,并使用 wait
family 。所以你必须找个好地方等孩子。
一种选择是设置 SIGCHLD
处理程序并在那里执行 waitpid(0,& status,WNOHANG)
。一定要循环,直到它不再找到任何进程 - 如果两个孩子在短时间内死亡,你可能只得到一个 SIGCHLD
。
另一种选择是双叉 - 即 fork()
,让孩子(称之为子A)再次分叉,拥有第二个子(孩子B)exec。然后孩子A立即退出。同时父亲是孩子A的 wait()
。一旦孩子A离开,系统的初始化过程将在孩子B最终死亡时负责收割。这种方法比较简单,但是你的shell无法知道子B何时死亡,所以如果你需要这些信息,请使用前一种方法。
其他提示
但是......但是......僵尸是一个孩子(在某种程度上)并且正在检查的过程是父母,对吗?所以如果你担心特定的pid是僵尸,为什么不用 WNOHANG
做一个 waitpid(2)
并摆脱它呢?现在,这将消耗退出状态,因此如果某个其他进程可能希望将来真正 wait
,这可能是一个坏主意。
你提到你正在构建一个Unix shell;您应该阅读:正确处理SIGINT / SIGQUIT
通常情况下,shell会在打印其提示之前不久检查已解散的子项 - 使用 waitpid(2)
系统调用和 WNOHANG
选项,如前所述。您可能还需要一个SIGCHLD处理程序 - 但是如果您正忙着等待某个前台进程终止并且它实际上是一个终止的后台进程,那么您必须决定要对该信息做什么。
这只是当前所选答案的一个小变化。
那么shell命令'ps'会显示活动进程表,你可以在其中发现进程“已经不存在”?我想必须有办法从c代码中获取这些信息。