如何防止出现僵尸进程

作者:wuxinliulei
链接:https://www.zhihu.com/question/29378056/answer/70645585
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

#include <stdio.h>
#include <unistd.h>
 
int main()
{
    int pid = fork();
    if ( pid > 0 )
    {
        while ( 1 )
        {
            sleep(3);
        }
    }
    else if ( pid == 0 )
    {
        printf("i die\n");
    }
}

上述程序中,fork了一个子进程,并且子进程很快就退出。父进程持续进行sleep,这样子进程就变成了僵尸进程。利用ps命令可以清晰的看到这一点。

 

[leconte@localhost ~]$ps axu |greptest
leconte  32600  0.0  0.0   1516   268 pts/1    S+   20:43   0:00 ./test
leconte  32601  0.0  0.0      0     0 pts/1    Z+   20:43   0:00 [test] <defunct>
leconte  32603  0.0  0.1   5024   668 pts/2    R+   20:43   0:00 grep test

 

Z+代表进程32601是僵尸进程。

僵尸进程和孤儿进程的区别是,孤儿进程是子进程还在运行,而父进程挂了,子进程被init进程收养。僵尸进程是父进程还在运行但是子进程挂了,但是父进程却没有使用wait来清理子进程的进程信息,导致子进程虽然运行实体已经消失,但是仍然在内核的进程表中占据一条记录,这样长期下去对于系统资源是一个浪费。

这时候杀掉父进程即可清理该僵尸进程。当然这并非长久之计,根本的办法是从代码上进行控制,防止类似的事情再发生。常见的方法无非是处理父进程的SIGCHLD信号,在信号处理函数里用wait或者waitpid等函数进行处理。更改后的代码如下:

 

#include <stdio.h>
#include <unistd.h>
#include <wait.h>
 
void* handler(int sig)
{
    int status;
 
    if (waitpid(-1, &status, WNOHANG) >= 0)
    {
        printf("child is die,i know\n");
    }
}
 
int main()
{
    signal(SIGCHLD,handler);
    int pid = fork();
    if ( pid > 0 )
    {
        while ( 1 )
        {
            sleep(3);
        }
    }
    else if ( pid == 0 )
    {
        printf("i die\n");
    }
}

这样更改后执行的输出如下:

 

[leconte@localhost test]$ ./test
i die
child is die,i know

可见父进程已经成功地处理了子进程的退出信号,子进程彻彻底底的消失了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值