进程学习:4-僵尸进程

一、僵尸进程:当前进程运行结束,但其资源没有被回收;


二、验证方法:
1.用fork函数创建两个进程,让子进程退出,父进程不调用wait/waitpid为子进程回收资源;(代码如下)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{   
    pid_t pid;

    if( (pid = fork()) < 0)
    {
        perror("fork error");
        exit(1);    
    }
    else if(pid == 0)
    {
        printf("im child\n");
    }
    else if(pid > 0)
    {
        printf("im farther\n");
        while(1)
            ;
    }

    return 0;
}

2.编译-执行,如下图;
僵尸进程
3.新建另一个终端(shift+Ctrl+n),然后输入查看进程命令 ps -ajx, 现象如下图(Z+:前台运行的僵尸进程);
僵尸现象


三、僵尸进程的危害
由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 那么会不会因为父进程太忙来不及wait子进程,或者说不知道 子进程什么时候结束,而丢失子进程结束时的状态信息呢?

不会。因为UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。


四、避免方法(具体方法见下一博客)
1.让父进程先于子进程退出,即让子进程成为孤儿进程,此时,子进程会被1号进程(init进程)所收养,当子进程结束时,1号进程会为子进程回收系统资源(APUE中讲了调用两次fork,形成一个孙子进程,让孙子进程变成孤儿进程来避免僵尸进程);
2.父进程调用wait函数及waitpid函数,以阻塞或非阻塞轮训的方式来等待子进程的退出,并为子进程回收系统资源;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值