6

我有一个子进程,它只是exit(0). 它变成了僵尸。有没有办法在没有父进程waitwaitpid在父进程中删除它?

R+  ./server //parent
R+  ./server //child
Z+  (server) //child zombie 
4

3 回答 3

7

您可以捕捉到SIGCHLD信号(例如使用sigaction(2)等...)。请注意,很少有函数可以安全地从信号处理程序调用。多次阅读signal(7) & signal-safety(7)。在信号处理程序内部做的一件好事就是设置一些volatile sigatomic_t标志(稍后您将在信号处理程序之外进行测试,例如在某个事件循环中)。或者,您可以在初始化时设置一个管道(7)(到您自己的进程)并在您的信号处理程序中写入几个字节(并在其他地方轮询(2)读取端),如Qt 所建议的那样

并且可以告诉waitpid(2)不要停止WNOHANG

如果您从不等待您的子进程,它将成为僵尸

阅读高级 Linux 编程。它有一个关于过程的好章节。

于 2013-05-03T17:05:23.700 回答
6

最简单的是让 SIGCHLD 在父级中被忽略:

signal(SIGCHLD, SIG_IGN);

之后,退出的子进程将完全消失,无需等待。

注意:这是一种快速而肮脏的方法,并假设您根本不关心子进程的退出状态,或者它何时退出。如果您确实关心,就像您在真正强大的应用程序中可能应该关心的那样,那么请参阅另一个答案,即创建适当的信号处理程序函数。

补充:这在 Unix 中不是通用的,但至少在 Linux 上有效。根据UNIX FAQ,这是 POSIX 中未定义的行为。此 Mac OS X 手册页表明此行为是在 FreeBSD 5.0 中引入的,并且适用于例如 OS X。

于 2013-05-03T17:15:24.450 回答
2

您可以使用双重fork技术:

创建一个子子进程。并在此之后立即终止子进程。这样子子进程就会走下init进程。该init进程将在退出时自动等待子子进程。

这不会删除waitpid,因为父进程必须等待子进程结束。因为子进程的生命周期总是很短,你可以waitpid从父进程调用而不会长时间阻塞。

有关更多信息,请参阅本文

于 2013-05-05T09:10:42.623 回答