我正在编写一个服务器,使用fork()
生成客户端连接的处理程序。 服务器不需要知道分叉进程发生了什么-它们可以自己工作,完成任务后应该死亡而不是变成僵尸进程。 有什么简单的方法可以实现这一点?
我正在编写一个服务器,使用fork()
生成客户端连接的处理程序。 服务器不需要知道分叉进程发生了什么-它们可以自己工作,完成任务后应该死亡而不是变成僵尸进程。 有什么简单的方法可以实现这一点?
有几种方法,但是在父进程中使用带有 SA_NOCLDWAIT
的 sigaction
可能是最简单的一种:
struct sigaction sigchld_action = {
.sa_handler = SIG_DFL,
.sa_flags = SA_NOCLDWAIT
};
sigaction(SIGCHLD, &sigchld_action, NULL);
signal(SIGCHLD, SIG_IGN);
,意思是忽略子进程结束信号。 - domsson使用双重fork。让您的孩子立即复制另一个副本,并使原始子进程退出。
http://thinkiii.blogspot.com/2009/12/double-fork-to-avoid-zombie-process.html
在我看来,这比使用信号更简单且更易理解。
void safe_fork()
{
pid_t pid;
if (!pid=fork()) {
if (!fork()) {
/* this is the child that keeps going */
do_something(); /* or exec */
} else {
/* the first child process exits */
exit(0);
}
} else {
/* this is the original process */
/* wait for the first child to exit which it will immediately */
waitpid(pid);
}
}
如何消除僵尸进程?
你不能像杀死普通进程一样使用SIGKILL信号来杀死僵尸进程,因为僵尸进程无法接收任何信号。所以养成良好的习惯非常重要。
那么在编程时,如何消除大量的僵尸进程?根据上述描述,当子进程死亡时,它将向父进程发送SIGCHLD信号。默认情况下,系统会忽略此信号,因此最好的方法是在信号处理函数中调用wait(),这可以避免僵尸进程在系统中滞留。 了解更多信息:http://itsprite.com/how-to-deep-understand-the-zombie-process-in-linux/