僵尸进程是指完成执行,但是仍有一个对应的PCB残留在进程表中,处于终止态的进程
一般而言,僵尸进程会被父进程wait进行回收,如果没有得到回收或者父进程还没退出,那么就会如同zombie一样一直残留
怎么产生
例如在socket中父进程大量地进行fork,并且没有wait,那么子进程结束之后就会变成僵尸进程
如何处理—信号量signal
子进程完成之后,系统会发送SIGCHLD信号给父进程
然而父进程对其默认处理是直接忽略,要想处理僵尸进程,那么需要使用wait来回收
那么如何处理信号量呢?下面我们将对signal(...), wait(...), waitpid(...)
等函数进行说明
signal
1 |
|
- signum : 需要处理的信号类型
- handler : 处理方案
wait & waitpid
1 |
|
当子进程完成,就会发送SIGCHLD信号给父进程,这时候,我们可以通过在handler中调用wait回收僵尸进程
1 |
|
但是,这个方案存在缺陷,如果在同一时间有多个SIGCHLD传来,那么只会有一个僵尸进程得到回收
因此,正确的解决方案是调用waitpid1
2
3
4
5
6
7
8void sig_chld(int signo) {
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf("chlid %d terminated\n", pid);
}
}