SIGCHLD信号丢失后的僵尸进程处理方案
[TOC]
在UNIX环境高级编程中有提到,有如下一段代码:
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0){
printf("child %d terminated\n", pid);
}
return;
}
刚开始看的时候,感觉很疑惑,为什么要在SIGCHLD的回调函数中使用循环。仔细分析一下原因如下:
- sigchld是不可靠的信号,进程就不可能对sigchld进行排队,即当有多个子进程同时退出时,会导致主进程只会受到一次信号,其他的信号会被丢弃。
- 如果使用主进程做子进程的管理和回收,发生丢弃情况,会导致子进程变成僵尸进程。
while(waitpid())的作用,是只要有一次信号被触发,就会循环处理所有的子进程退出。
关键点: waitpid 和 SIGCHLD 没关系,即使是某个子进程对应的 SIGCHLD 丢失,只要父进程在任何一个时刻调用了 waitpid,那么这个子进程还是可以被回收的。