僵尸进程的分析

来源:互联网 发布:制作画册的软件 编辑:程序博客网 时间:2024/05/22 18:16

僵尸进程产生

 Linux进程退出并不代表被删除

在Linux环境下,当某个进程退出时并不代表该进程在系统中已经被删除,还有一些包含进程状态等数据保存在系统中,若不人为进行删除,则会一直囤积在系统中,久而久之就会产生大量剩余数据。

僵尸进程基本概念

Linux系统中,出了Init进程,其他所有进程都是通过parent进行fork出来的,我们成为child进程,当child进程退出后,内核中包含child进程的数据没有被删除,这种情况就是僵尸进程。一般情况下,每个进程在退出之后,都会发送一个SIGCHLD信号给它的parent进程,默认情况下,parent进程是不处理该信号事件。

僵尸进程产生的条件

当child进程退出时候,系统会发送一个SIGCHLD信号给它对应的parent进程,parent进行若不处理该信号,则会产生僵尸进程现象,若通过调用wait() 或者waitpid()函数则会处理该事件,就不会产生僵尸进程。

对于child进程和parent进程来说,有两种情景,就是谁先退出,若parent进程先退出,则child进程会被托付给Init进程,Init进程则有对SIGCHLD信号的处理,不会产生僵尸进程;若child进程先退出,parent进程一直没有退出,也没有执行对SIGCHLD信号处理操作,则会产生僵尸进程。

僵尸进程产生实例

我们利用ps命令可以查看僵尸进程,一般具有标志:


#include <stdio.h>#include <stdlib.h>int main(){pid_t pid,pr;pid = fork();switch(pid){case -1:printf("error");exit(EXIT_FAILURE);case 0:                printf("child process\n");break;default:printf("parent pid = %d\n",getpid());while(1)sleep(2);}exit(0);}

 上面实例中,由于parent进程一直处于运行状态,child进程退出时候,parent并没有调用wait() 或者waitpid() 函数操作,就会产生僵尸进程。

运行该应用后,执行ps命令:


qq@qq-Aspire-TC-606:~/qqzhong/tmp/c$ ps auxw|grep zombieqq   4100  0.0  0.0   4196   356 pts/1    S+   16:41   0:00 ./zombie_tmpqq   4101  0.0  0.0      0     0 pts/1    Z+   16:41   0:00 [zombie_tmp] <defunct>

如何避免僵尸进程

fork  和 wait 成对出现

上面我们可以看到,产生僵尸进程的条件,为了避免产生僵尸进程,必须是吸纳fork 和 wait成对出现,wait在fork之后进行调用。

避免产生僵尸进程实例

根据上面的实例,我们增加处理操作,代码如下:

#include <stdio.h>#include <stdlib.h>int main(){pid_t pid,pr;pid = fork();switch(pid){case -1:printf("error");exit(EXIT_FAILURE);case 0:                printf("child process\n");break;default:printf("parent pid = %d\n",getpid());while(pr = wait(NULL) !=-1);while(1)sleep(2);}exit(0);}

运行该应用,通过ps命令查看后如下

qq@qq-Aspire-TC-606:~/qqzhong/tmp/c$ ps auxw|grep zombieqq   4147  0.0  0.0   4196   356 pts/1    S+   16:45   0:00 ./zombie_tmp




0 0