如何检查pid为X的进程是否是僵尸进程?
我获得了一个进程的 PID,我需要使用 C 中的 POSIX 系统调用来检查它是否是僵尸进程。我应该怎么做?
我遇到的问题是,我有一个进程,它分叉成许多子进程,这些子进程都执行执行操作,有时我想在后台执行执行操作,所以我不能真正 wait() 进入后台的子进程。我可以定期 wait() (一次在我的主循环中),但我需要知道哪些进程是僵尸进程,以便我的父亲进程在等待不会很快结束的子进程时不会挂起。
如果您好奇,我正在构建一个 unix shell,并且 shell 的本质是让子进程异步运行。
I got the PID of a process and I need to check if it is a zombie using POSIX system calls in C. How should I do that?
The problem I'm having is that I have a process and it forks into many children, the children all do execs and sometimes I want to do the exec in background so I can't really wait() the children that go in background. I could wait() periodically (once in my main loop) but I need to know which processes are zombie so my father process doesn't hang while waiting for children that are not going to end soon.
If you are curious, I'm building a unix shell and it is in the shell nature to have the children processes behaving asynchronously.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您无法通过纯 POSIX 调用检查进程是否为僵尸进程 - 除非您是父进程,并使用
等待
家人电话。所以你得找个好地方等孩子。一种选择是设置一个 SIGCHLD 处理程序并在其中执行 waitpid(0, &status, WNOHANG) 。请务必循环直到它不再找到任何进程 - 如果两个子进程在短时间内死亡,您可能只会收到一个
SIGCHLD
。另一种选择是双重 fork - 即,
fork()
,让子级(称为子级 A)再次 fork,让第二个子级(子级 B)执行。然后孩子A立即退出。与此同时,父进程正在wait()
等待子进程 A。一旦子进程 A 消失,系统的 init 进程将在子进程 B 最终死亡时负责回收它。此方法更简单,但您的 shell 将无法知道子 B 何时死亡,因此如果您需要该信息,请使用前一种方法。You can't check whether a process is a zombie with pure POSIX calls - except where you're the parent process, and reaping it with a
wait
family call. So you'll have to find a good place to wait for the child.One option is to set a
SIGCHLD
handler and do awaitpid(0, &status, WNOHANG)
there. Be sure to loop until it no longer finds any processes - if two children die within a short interval, you may only get oneSIGCHLD
.Another option is to double fork - that is,
fork()
, have the child (call it child A) fork again, have the second child (child B) exec. Then child A immediately exits. Meanwhile the parent iswait()
ing for child A. Once child A is gone, the system's init process will take care of reaping child B when it eventually dies. This method is simpler, but your shell will have no way of knowing when child B dies, so if you need that information, use the former method.但是..但是..僵尸是一个孩子(在某种程度上),而正在检查的进程是一个父母,对吧?因此,如果您担心特定的 pid 是僵尸,为什么不直接使用
WNOHANG
执行waitpid(2)
并摆脱它呢?现在,这将消耗退出状态,因此如果其他进程将来可能想要真正等待,这可能是一个坏主意。But .. but .. the zombie is a child (at some level) and the process that's checking is a parent, right? So if you are concerned that a specific pid is a zombie why not just do a
waitpid(2)
withWNOHANG
and get rid of it? Now, this will consume the exit status, so it may be a bad idea if some other process might want to reallywait
in the future.你提到你正在构建一个 Unix shell;你应该阅读以下内容: 正确处理 SIGINT/SIGQUIT
You mention that you are building a Unix shell; you should read this: Proper handling of SIGINT/SIGQUIT
通常,shell 在打印提示符之前不久会检查已失效的子进程 - 使用
waitpid(2)
系统调用和WNOHANG
选项(如前所述)。您可能还需要一个 SIGCHLD 处理程序 - 但如果您正忙于等待某个前台进程终止并且它实际上是一个终止的后台进程,则您必须决定如何处理该信息。这只是当前所选答案的微小变化。
Normally, the shell checks for defunct children shortly before printing its prompt - using the
waitpid(2)
system call and theWNOHANG
option as already discussed. You might also want a SIGCHLD handler - but you'd have to decide what you're going to do with the information if you're busy waiting for some foreground process to terminate and it is actually a background process that terminates.This is only a minor variation on the currently selected answer.
那么 shell 命令“ps”又如何呢?它显示了活动进程表,您可以在其中找到进程“失效”的情况?我想一定有一种方法可以从 C 代码中获取该信息。
And what about the shell command 'ps' which shows you the table of active processes where you can find that an process is 'defunct'? I suppose there must be a way to get that information from c code.