87-Linux的僵死进程及处理方法

僵死进程

在这里插入图片描述
我们的程序在退出的时候:return 0,exit(0),之类的,这个0就是退出码,状态信息,这个东西存储在当前进程的PCB中,会有一个整型值来存储退出码。
当我们子进程结束以后,会把退出码写到PCB中,然后希望父进程可以获得到这个退出码,然后父进程就可以看到子进程是正常运行结束还是出错退出。正常的话我们return 0,失败的话我们return -1
在这里插入图片描述
正常我们的进程结束,比如说子进程结束,这个进程实体就会被释放掉,接下来会把PCB也移除,这样子,整个操作系统中就再也找不到它了,但是,linux设计的时候:当子进程结束以后,这个进程实体就没有,但是这个PCB会把暂时保留下来,父进程去获取子进程PCB的退出码,然后再删除这个子进程的PCB,这个子进程就彻底消失了,如果父进程不去获取,那么这个PCB就一直保留着,此时子进程已经结束了,退出了,这个子进程的PCB的状态是僵死状态。此时我们去ps,看系统运行的进程,我们还可以观察到这个子进程,因为其PCB还在,但是这个进程不可能去执行了,因为是僵死状态,但是僵死状态不会持续太长时间。父进程有义务去处理子进程,不要让他变成僵死进程!

(1) 僵死进程概念:子进程先于父进程结束,父进程没有调用 wait() 获取子进程的退出码。
(2) 如何处理僵死进程:父进程通过调用 wait()获取子进程退出码。 或者等父进程结束,Init进程收养孤儿进程,调用wait()获取子进程退出码。
(3) Init 进程收养孤儿进程,而且Init 进程“尽心尽责”,会自动调用wait()获取子进程退出码。

代码示例:
先给出一个能产生僵死进程的代码
在这里插入图片描述
运行结果如下图:
在这里插入图片描述
从上图中可以看到,当子进程结束后,并没有消失,仍然可以在系统中观测到,但此时子进程其实已经运行结束了,此时子进程的状态被称为僵死状态,系统把处于该类状态的进程称为僵死进程< defunct >
如果父进程先结束,子进程最后是不会变为僵死进程的。

处理方法

在这里插入图片描述
僵死进程产生了,会有什么影响?
如果只有一两个僵死进程,没有什么影响。
如果有很多个僵死进程,持续不断的产生,就有影响了,因为子进程的PCB如果没有被释放,进程的pid就被一直占着,在内核空间中,PCB本身是结构体,会占用内存空间,对系统软硬件资源损耗。我们要避免僵死进程的产生,父进程有义务去处理!
在这里插入图片描述
我们需要传入一个整型变量的地址,它会把退出码写到这个整型变量里面,然后返回值就是获取哪个子进程的退出码的进程的pid
在这里插入图片描述

如下代码,处理了僵死进程,子进程结束后,会消失:
在这里插入图片描述

运行结果如下,在此解释一下,我是在后期将代码中的exit(0)改成exit(3),方便更好地显示主函数的返回值,下面这个运行结果是在exit(0)的情况下运行出来的结果,此时主函数返回值0,val=0
在这里插入图片描述
显而易见,int val = 0; pid_t id = wait(&val); 的执行起到了阻塞作用,因为要获取子进程的退出码,如果子进程还没有结束,就获取不到,父进程就阻塞住了,先将子进程执行完后,获取到退出码了,才开始执行父进程。所以今后写程序需进行多重考虑。
可以配合信号量
子进程的退出码

下面这个运行结果是在exit(3)的情况下运行出来的,此时主函数返回值是3,打印的是768
在这里插入图片描述
在这里插入图片描述
把3左移了8位,因为退出码一般来说是128以内的值,但是一个整型有4字节,1个字节本来就够存储退出码了,其他3个字节有别的作用了,所以在这里就发现被移位了,存储在该存储的位上。我们这怎么处理?操作位是不大方便的,但是系统给我们提供了
如果程序是正常退出,就执行下面的第二个宏在这里插入图片描述
还有一种情况,这个程序没有执行到exit,就被kill掉了,获取的就是异常中止的信号,我们就用下面这个去判断在这里插入图片描述
下面这个宏判断程序是不是正常结束(执行exit),如果是,
在这里插入图片描述
就通过下面这个宏得出退出码,这个宏就知道我们的退出码是在4个字节中的哪个字节存放的,它就会去那个地方拿到,此时拿到的就是我们设定的3了,不是768了。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
从上图可以看到子进程结束后,彻底从系统中消失了,并没有变成僵死进程。

孤儿进程

父进程结束以后,子进程就没有父进程,系统对没有父进程的子进程叫做孤儿进程,孤儿进程再重新寻找一个父进程,这个新的父进程是:init进程,它的进程pid是1,也就是第一个被fork出来的进程,它会收养那些没有父进程的子进程,它收养这些子进程后,不管哪个子进程结束,这个init进程就会直接去通过wait去获取它的退出码,它一定会保证它的子进程不会成为僵死进程,子进程一旦结束,就获取退出码,然后系统一删,就没有这个进程了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
父进程结束会给出图中的黑色的提示符,父进程也就是main结束了
父进程结束后,我们看孤儿进程的父进程变为pid=1的init进程了
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值