Linux---模拟实现僵尸进程和孤儿进程

我们先了解一下进程都有哪几种状态。
kernel源代码里定义了进程的如下状态:
· R 运行状态(running):表明进程要么是在运行中要么是在运行队列里。
· S 睡眠状态(sleeping):意味着进程在等待事件完成,有时叫做可中断睡眠。
· D磁盘休眠状态(Disk sleep):不可中断睡眠状态,在这个状态进程通常会等待I/O的结束。
· T 停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止进程。这个暂停的进程可以通过发送SIGCONT信号让进程继续运行。
· X 死亡状态(dead):只是一个返回状态,不会在任务列表里看到。
· Z 僵尸状态(zombie):当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸状态。僵尸进城会以终止状态保持在进程表中,会一直等待父进程读取退出状态信息。

我们知道,在unix/linux中,正常情况下,子进程由父进程创建,子进程可以再创建新进程。子进程的退出和父进程的运行是一个异步的过程,即父进程永远无法预测子进程到底什么时候结束。当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。
1.僵尸进程
父进程通过fork()创建子进程,子进程退出后,父进程并没有调用wait或waitpid获取子进程的状态信息,这时子进程就成为僵尸进程。
测试代码:

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

int main()
{
    pid_t pid = fork();//创建子进程
    if(pid < 0)
    {
        perror("fork error");
        exit(1);
    }
    else if(pid == 0)//子进程
    {
        printf("child process [%d] is running!\n",getpid());
        sleep(5);
        exit(EXIT_SUCCESS);//5秒后子进程退出
    }
    else//父进程
    {
        printf("I am father!\n");
        sleep(20);
        printf("father process [%d] is running!\n",getpid());

    }
    return 0;
}

测试结果:
这里写图片描述
僵尸进程的危害:
我们知道,在创建进程的时候会给他分配相应的系统资源,如果子进程退出后,父进程不进行回收,那么它所占用的那块资源也就不会释放,就会造成内存泄露。

2.孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
测试代码:

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

int main()
{
    pid_t pid = fork();//创建子进程
    if(pid < 0)
    {
        perror("fork error");
    }
    else if(pid == 0)//子进程
    {
        printf("I am child [%d] ,I am running.[%d] is my father!\n",getpid(),getppid());
        sleep(20);
    }
    else//父进程
    {
        printf("I am father [%d],I will die soon!\n",getpid());
        sleep(10);
        exit(EXIT_SUCCESS);//10秒后父进程退出
    }
    return 0;
}

测试结果:
这里写图片描述
10秒后,父进程退出,子进程被1号进程收养。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/y6_xiamo/article/details/80148340