为什么需要僵尸进程?
在父进程执行wait之前,其子进程就已经终止,这将会发生什么?此处的重点在于: 即使子进程已经结束,系统仍然需要允许父进程在其之后的某一时间去执行wait,来获取子进程的结束状态
所以内核将子进程转为僵尸进程来完成情况的处理,无法通过信号来杀死僵尸进程,这保证了父进程总是能够使用wait方法。这时候会释放子进程把持的大部分资源。以便供其他进程重新使用,其所保留的仅有内核进程表中的一条记录(其中包含了进程ID、终止状态、资源使用状况等信息)
长寿僵尸进程
子进程先执行,退出之后的两种情况:
- 当父进程执行完wait后,不再需要子进程剩余的最后信息,内核会将删除僵尸进程
- 父进程没有执行wait并退出之后,init进程将接管子进程,并自动调用wait,从而删除僵尸进程
所以:
- 一个长周期的父进程,应该总是执行wait方法,以防止僵尸进程的大量产生,导致无用的信息填满内核进程表
- 杀死僵尸进程的唯一方法是:杀死其父进程,从而使init进程接管僵尸进程,并移除僵尸进程
具体避免长寿僵尸进程的几种方法:
- 父进程调用wait方法来接受子进程。一种为阻塞式,一种为非阻塞轮询方式 2.使用SIGCHLD信号处理程序:可以对SIGCHLD信号安装处理程序,来对子进程的终止做出反应,在其中wait子进程,因为信号的中断处理方式,导致处理函数需要避免几个问题: 1)防止信号丢弃,导致少调用wait方法 2)需要提前安装信号处理器 3)因信号传递特征需要信号处理器避免的通病
- 显式的忽略终止的子进程: 显式的将SIGCHLD 处置为SIG_IGN, 系统在子进程终止后立即删除,没有转换为僵尸进程的状态过程,也不需要wait调用。不过较老的UNIX实现并不能够正确处理这样的情况,导致不具有可移植性
几篇关于僵尸进程的文章参考: