Linux应用编程 | 孤儿进程及僵尸进程

孤儿进程
在Linux/Unix环境中,我们是通过fork函数来创建子进程的。创建完毕之后,父子进程独立运行,父进程无法预知子进程什么时候结束。通常情况下,子进程退出后,父进程会使用wait或waitpid函数进行回收子进程的资源,并获得子进程的终止状态。
但是,如果父进程先于子进程结束,则子进程成为孤儿进程。孤儿进程将被init进程(进程号为1)领养,并由init进程对孤儿进程完成状态收集工作。
因此,孤儿进程是没有父进程的进程,它在完成自己的工作退出之后,init进程将完成孤儿进程的善后工作,回收它的资源,因此孤儿进程并不会有什么危害。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid;
    pid = fork();
    if (pid == 0) {
        while (1) {
			/* 子进程死循环,保证不死 */
            printf("I am child, my parent pid = %d\n", getppid());
            sleep(1);
        }
    } else if (pid > 0) {
			/* 父进程睡眠3秒后退出 */
            printf("I am parent, my pid is = %d\n", getpid());
            sleep(3);
            printf("------------parent going to die------------\n");
    } else {
        perror("fork");
        return 1;
    }
    return 0;
}


僵尸进程
而如果子进程先于父进程退出,同时父进程太忙了,无瑕回收子进程的资源,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。 
内核对于进程的退出有一套固定的机制,就是会释放该进程所有的资源,包括打开的文件,占用的内存等。但仍然有一部分信息残留在内核中,比如:进程号,退出状态,运行时间等。一般来说,父进程会调用wait或waitpid来获取子进程的退出状态,子进程的资源也随之释放。但如果父进程陷入死循环或没有调用wait/waitpid函数的话,那么子进程残留的信息将得不到释放,会一直占用内核资源。而内核的资源一般是非常宝贵的,因此如果产生大量的僵尸进程的话,将严重影响系统的性能,应避免僵尸进程的产生。
杀死僵尸进程的方法:
如其名,僵尸进程其实已经就是退出的进程,因此无法再利用kill命令杀死僵尸进程。僵尸进程的罪魁祸首是父进程没有回收它的资源,那我们可以想办法它其它进程去回收僵尸进程的资源,这个进程就是init进程。因此,我们可以直接杀死父进程,init进程就会很善良地把那些僵尸进程领养过来,并合理的回收它们的资源,那些僵尸进程就得到了妥善的处理了。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid;
    pid = fork();
    if (pid == 0) {
            printf("I am child, my parent= %d, going to sleep 3s\n", getppid());
            sleep(3);
            printf("-------------child die--------------\n");
    } else if (pid > 0) {
            printf("I am parent, pid = %d, myson = %d, going to sleep 5s\n", getpid(), pid);
            sleep(5);
			system("ps -o pid,ppid,state,tty,command");
    } else {
        perror("fork");
        return 1;
    }

    return 0;
}



作者介绍
本人是一名Linux应用开发工程师,目前供职于一家世界500强公司,主要负责车联网产品的研发。喜交天下好友,欢迎关注本人公众号一起学习、交流!

猜你喜欢

转载自blog.csdn.net/yychuyu/article/details/80200917