僵尸进程与孤儿进程

原文:https://mp.weixin.qq.com/s/c9mpsICWMLarP5Pd0cX_DQ

 

在被誉为UNIX编程“圣经”的一书《unix环境高级编程》中有提到僵尸进程和孤儿进程。不少同学对这两个概念会混淆,这篇文章总结一下。

在unix/linux系统中,大多情况下,子进程是通过父进程fork创建的,注:系统调用fork,是一个比较有意思系统调用,它调用一次,返回两个值,失败返回-1,成功时在子进程返回0,父进程返回所创建子进程的pid。本文暂时只需了解这些就够了,有兴趣的同学可以查阅man文档,描述的非常清楚。

子进程创建后,子进程的结束和父进程的运行是一个异步过程,也就是说父进程没办法预测子进程什么时候结束。 当一个子进程完成它的工作终止之后,其父进程需要调用wait()或waitpid()去获取子进程的终止状态。

 

孤儿进程

首先来认识下什么叫孤儿进程,所谓孤儿进程,顾名思义,和现实生活中的孤儿有点类似,当一个进程的父进程结束时,但是它自己还没有结束,那么这个进程将会成为孤儿进程。最后孤儿进程将会被init进程(进程号为1)的进程收养,当然在子进程结束时也会由init进程完成对它的状态收集工作,因此一般来说,孤儿进程并不会有什么危害。

下面看一个关于孤儿进程的例子:在main函数中,创建子进程,然后让父进程睡眠1s,让子进程先运行打印出其进程id(pid)以及父进程id(ppid);随后子进程睡眠3s(此时会调度到父进程运行直至结束),目的是让父进程先于子进程结束,让子进程有个孤儿的状态;最后子进程再打印出其进程id(pid)以及父进程id(ppid);观察两次打印 其父进程id(ppid)的区别。

 

从运行结果来看:当其父进程结束后,子进程成为了孤儿进程,其父进程id(ppid)为1,也就是说,init进程成为该子进程的父进程了。

 

僵尸进程

 

好了,说完了孤儿进程,再来谈谈僵尸进程,其实对于这2两个概念(指孤儿进程与僵尸进程)不少人容易混淆,其实如果仔细理解的话,还是很容易区分的。

僵尸进程是指:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的某些信息如进程描述符仍然保存在系统中。这种进程称之为僵死进程。

下面是1个关于僵尸进程的例子:在main函数中,创建子进程,然后让父进程睡眠10s,让子进程先终止(注意和孤儿进程例子的区别);这里子进程结束后父进程没有调用wait/waitpid函数获取其状态,用ps查看进程状态可以看出子进程为僵尸状态。

 

 

 

注:任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理这是每个子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。  如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

讲了僵尸进程产生的原因,再来讲讲僵尸进程的危害:僵尸进程会在系统中保留其某些信息如进程描述符、进程id等等。以进程id为例,系统中可用的进程id是有限的,如果由于系统中大量的僵尸进程占用进程id,就会导致因为没有可用的进程id系统不能产生新的进程,这种问题可就大了,这就是僵尸进程带来的危害。因此大部分情况下,我们都应当避免僵尸进程的产生,至于如何避免僵尸进程的产生,本来想这一篇总结完,不过感觉已经昏昏欲睡,一看时间快凌晨一点了,因此只能拖到下一篇单独总结了。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值