SIGCHLD信号丢失后的僵尸进程处理方案

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的回调函数中使用循环。仔细分析一下原因如下:

  1. sigchld是不可靠的信号,进程就不可能对sigchld进行排队,即当有多个子进程同时退出时,会导致主进程只会受到一次信号,其他的信号会被丢弃。
  2. 如果使用主进程做子进程的管理和回收,发生丢弃情况,会导致子进程变成僵尸进程。
  3. while(waitpid())的作用,是只要有一次信号被触发,就会循环处理所有的子进程退出。

关键点: waitpid 和 SIGCHLD 没关系,即使是某个子进程对应的 SIGCHLD 丢失,只要父进程在任何一个时刻调用了 waitpid,那么这个子进程还是可以被回收的。