java怎么运行孤儿进程_每天3分钟操作系统修炼秘籍(29):僵尸进程和孤儿进程...

僵尸进程

进程从退出开始,到它的退出状态信息被父进程的wait/waitpid读走,在这个阶段中,进程将仍然存在于内核进程表中,这个阶段的进程的状态是终止态或称为僵尸态。而僵尸态进程称为僵尸进程,而父进程读子进程退出状态信息的动作则称为"reap"(这是一个术语,含义是收割、收走),即为子进程收尸。

由此可知,任何一个进程一定都会有一个僵尸态的阶段,只不过正常情况下这个阶段持续的时间很短,短到这个状态无法被ps等工具捕获,因为进程切换的时间是非常短的。但是,如果父进程一直不调用wait或waitpid,那么退出的子进程将一直处于僵尸态,即永久的僵尸,这个时候ps等工具就能捕获到该进程的僵尸态。

虽然说僵尸进程听上去很可怕,但实际上僵尸进程的影响并不大。首先,它不占用任何CPU资源,因为它已经执行完成了,操作系统将不会调度到它(因为不在就绪队列中);其次,它占用的内存资源也非常少,仅占用一个进程表项的内存而已;最后,对于其它资源的占用(例如打开的文件描述符),也都基本完全释放了。所以,僵尸进程就算过多,也不会降低操作系统的性能。僵尸进程最大的影响是,当僵尸进程太多时,可能会占满Linux的进程表空间,使得无法再创建新进程,因为每个用户能够创建的进程数是有限的(ulimit -u命令可查看)。

在Shell下运行的所有命令,只要该命令不会产生子进程,就一定不会成为永久的僵尸进程,因为Shell启动命令的方式是fork+exec+wait,它会等待它的子进程终止并为子进程收尸。

但是,像Daemon类进程,这类进程一般会脱离终端脱离Shell进程,而且通常还会产生子进程,那么当子进程退出时,如果程序编码不完善,一直不去给子进程收尸,那么它的子进程将变成永久的僵尸进程。

解决僵尸进程的方式非常简单,杀掉僵尸进程的父进程即可。

孤儿进程

当进程的父进程先退出,那么这个子进程就会成为孤儿进程。所有的孤儿进程都会被pid=1的init进程收养,使得它们的父进程变成init进程,即PPID=1。

实际上,Shell下生成孤儿进程是非常容易的事情:

# (子)Shell中执行后台命令,(子)Shell退出后它就是孤儿进程

$ ( sleep 30 & )

$ ps -o pid,ppid,comm

PID PPID COMMAND

117281 117279 bash

122065 1 sleep # 这就是孤儿进程

122066 117281 ps

为了描述清楚子进程变成孤儿进程的过程,这里使用Shell伪代码描述下孤儿进程。

pid=$(fork) # 从此开始,有两个进程分支

if [ $pid -eq 0 ];then

echo "Child Process" # 子进程

sleep 10 # 子进程睡眠10秒

exit

fi

# 父进程睡眠3秒

sleep 3

上面代码中的父进程睡眠3秒后退出,退出后其子进程仍然在执行,它会转移到init进程之下被init收养,7秒之后子进程退出。由于该子进程的父进程变成init进程,于是init进程负责为该子进程收尸。

现在回头想想,为什么(sleep 30 &)的sleep进程为什么会变成孤儿进程?

如果,某个父进程下已经有永久的僵尸子进程,当这个父进程退出后,这些子进程都将被pid=1的init进程收养,而init进程有一个特性,它会在接收到子进程的时候检查检查子进程是否是僵尸进程,是的话就收尸。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值