孤儿进程与僵尸进程

先上僵尸进程的图:



使用第三方软件时,发现系统进程数异常,通过命令 ps - ef | grep defunct 发现很多僵尸进程,最后通过kill掉父进程,并修复了该BUG。

网上相关的资料很多很多,下面对孤儿进程和僵尸进程(僵死进程)再做些总结


概念

孤儿进程:fork编程时,对于父进程已经终止的所有进程,它们的父进程都改变为init进程,其操作过程大概如下,内核逐个检查所有活动的进程,以判断它是否是正要终止进程的子进程,如果是,则将该进程的父进程ID更改为1(init进程的ID),这种处理方法确保了每个进程都有一个父进程。

上图:

孤儿进程与僵尸进程_第1张图片

kill掉父进程45294后,子进程45295的父进程就更改为1了。


僵尸进程:fork编程时,如果子进程先于父进程退出,就会处于终止状态,内核为每个终止子进程保存了一定量的信息(进程ID、终止状态、使用的CPU时间总量等),所以当终止进程的父进程调用wait或者waitpid时,可以得到这些信息,并将终止子进程从系统进程表删除,释放终止状态。一旦父进程没有调用wait或者waitpid获取子进程的终止状态,那么进程表的信息就不会被移除,那么这些进程就会变成僵尸进程。


僵尸进程造成的资源泄露

1.系统的进程号是有限的,持续产生僵尸进程会耗尽所有的进程号

2.僵尸进程还会占用运行时分配的资源吗?比如内存、文件描述符?答案是不会。内核为每个终止子进程保存了一定量的信息(进程ID、终止状态、使用的CPU时间总量等),仅此而已,最大的危害还是耗尽进程号


如何避免僵尸进程

1.fork两次并杀死一级子进程,令二级子进程成为孤儿进程进而被init托管,具体实现代码可参考《unix环境高级编程》8.6节

2.父进程捕捉SIGCHLD信号,调用waitpid

3.父进程中对SIGCHLD信号的处理函数设置为SIG_ING(忽略信号),待验证


如何杀死僵尸进程

1.重启

2.杀死僵尸进程的父进程


参考:

《unix环境高级编程》第2版,第8章进程控制

维基百科:僵尸进程



你可能感兴趣的:(linux,进程)