我有一个只有exit(0)
的子进程。它变成了僵尸。有没有办法在父进程中没有wait
或waitpid
的情况下将其删除?
R+ ./server //parent
R+ ./server //child
Z+ (server) //child zombie
答案 0 :(得分:6)
您可以捕获SIGCHLD
信号(例如使用sigaction(2)等...)。注意,很少有函数可以从信号处理程序安全地调用。多次阅读signal(7)& signal-safety(7)。在信号处理程序中做一件好事就是设置一些volatile sigatomic_t
标志(稍后你会测试,在信号处理程序的之外,例如在某些event loop中)。或者,您可以在初始化时设置pipe(7)(到您自己的进程)并在信号处理程序中写入几个字节(并在其他地方读取poll(2)),如{{3} }。
可以告诉suggested by Qt不要停留在WNOHANG
如果您从不等待您的子进程,它将变为waitpid(2)。
阅读zombie。它有一个关于流程的好章节。
答案 1 :(得分:5)
最简单的做法是在父母中忽略SIGCHLD:
signal(SIGCHLD, SIG_IGN);
在此之后,退出子进程将干净利落地离开而无需等待。
注意:这是一种快速和肮脏的方法,并假设您根本不关心子进程的退出状态,或者它何时退出。如果你真的关心,你可能应该在一个真正强大的应用程序中,那么请参阅另一个答案,关于创建一个正确的信号处理函数。
补充:这在Unix中并不普遍,但至少在Linux上有效。根据{{3}},它是POSIX中未定义的行为。 an UNIX FAQ表明此行为是在FreeBSD 5.0中引入的,例如适用于OS X.
答案 2 :(得分:2)
您可以使用双fork
技术:
创建子子进程。并在此之后立即终止子进程。
通过这种方式,子进程将进入init
进程。 {child}进程会在子进程退出时自动等待子进程。
这不会删除init
,因为父级必须等待子进程的结束。
由于子进程的生命周期始终很小,因此您可以从父进程中调用waitpid
而不会长时间阻止。
有关详细信息,请参阅this article。