Linux-僵尸进程和孤儿进程

本文深入剖析了Linux环境下僵尸进程的产生原因及其处理方法,并通过实例演示了如何避免僵尸进程的出现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux,进程模型下,进程通过父进程产生子进程,子进程又产生子进程,子子孙孙又繁衍生息,每个子进程都有着各自的使命,相互配合,完成各项功能。当使命完成,子进程结束生命进程,被父进程回收。父进程调用wait()或者waitpid()系统函数取得子进程终止状态。如果一个子进程结束进程,他的父进程一直不读取他的退出信息,这些信息就会一直占用着资源,这些占用资源又不执行任务的进程,就会变成僵尸进程。

看看僵尸进程的定义:

进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息,此时进程成为僵尸进程

就好比一个人死亡,他的父亲总得知道他的死因,为他处理后事,但如果父亲无法为他及时处理后事,他就会一直在那占用着资源,携带者死亡的原因的信息,等待被人查看,着突然一个僵尸进程,他的父亲无法得之他的死因,也无法来替他收尸,他的遗体就一直在哪里占用着土地资源,成为一个僵尸。

在进程中同理,一个进程终止,总的有终止原因:是程序正常执行完终止,还是意外终止,总得有个说法,有信息反馈给父进程,在进程中,这些意外终止的信息存储在PCB中,

僵尸状态在结构体中的定义:EXIT_ZOMBIE

在这里补充进程的常见几种状态

状态含义
R正在执行状态
S浅度睡眠状态,可被唤醒,
D深度睡眠,不可不唤醒,除非自己醒来
T暂停状态,不做任何事
Z退出状态。成为僵尸进程
X退出状态,进程即将被销毁

状态演示

写一个小程序,演示一下僵尸进程,用fork创建一个子进程。

#include <stdio.h>
 #include <unistd.h>
#include <stdlib.h>
int main()
{
         pid_t pid;
         pid= fork();   //创建一个子进程
        if(pid==0)
        {
                printf("i am a child process\n");
                printf("pid:%d\tppid:%d\n",getpid(),getppid());
                exit(0);
        }
        else if(pid>0)
        {
                printf("i am a father process\n");
                printf("i will sleep five scores\n");
                sleep(5);       //父进程睡眠,等待子进程退出
                system("ps -o pid,ppid,state,tty,command\n");   //输出进程信息
                printf("father process is exited\n");
        }

        else
        {
                return -1;
        }
        return 0;


}


这里写图片描述
如果系统进程表一直被僵尸进程耗着,迟早会被耗尽,便无法创建新的进程,也无法执行其他任务,

僵尸进程的处理方法:

  1. 将子进程变成孤儿进程,从而他的父亲变成init进程,通过init进程处理僵尸进程
  2. 子进程退出时,向父亲发出“SIGGHILD”父亲处理”SIGGHILD”,在信号处理函数中调用wait()函数处理僵尸进程

孤儿进程

所谓孤儿进程,就是父进程先于子进程挂掉,子进程没有了父亲,变成了孤儿进程(orphan)

由于孤儿进程没有了父进程,当他终止时,没有父进程来回收他的资源,就会导致内存泄露,这是一个很严重的后果,为了解决这个问题,操作系统便派出1号进程领养该子进程。来处理子进程终止完后的资源回收。
下面来看下孤儿进程的演示效果
(还是以上面代码为例,这次我们让父进程先运行完)

#include <stdio.h>
 #include <unistd.h>
#include <stdlib.h>
int main()
{
     int ret= fork();
    if(ret==0)
    {
            printf("子进程PID:%d\n",getpid());
            sleep(10);
            exit(0);
    }
    else if(ret>0)
    {

            printf("父进程PPID:%d\n",getppid());
            sleep(3);
    }

    else
            return -1;
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值