對僵死進程的處理
前些天本人發了個關於daemon如何退出的貼。現請教高手后了解大概,希望與大家分享:
一、僵屍進程的産生
当子进程比父进程先运行结束,而父进程没有回收子进程的时候,子进程将成为一个僵尸进程。如果父进程先退出,子进程被init接管,子进程退出后init会回收,就没事了。
二、僵屍進程的危害
僵尸进程是一个运行完毕的进程,所有资源都已经释放了,除了它的进程表项。因此,导致的影响如下:如果操作系统最多能管理1000个进程,那么僵尸进程的存在,将会使得操作系统管理正常进程减少。
三、如何避免僵屍進程的産生
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收(没有试验过)
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收估计还要自己做。
四、总结
基本上僵尸进程的产生是因为父进程活得比子进程长,而且比较忙,或者太马虎,当子进程退出后,没有回收导致的。
注:以上内容纯属理论分析,有些内容没有经过试验,本着严谨的精神,建议各位有时间可以自己试验一下。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
作为daemon,4相对简单一些,是较为常用的做法;
如果不希望程序自动转后台,3是比较好的方法;
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收(没有试验过)
如果父进程不需要知道子进程的状态,直接忽略SIGCHLD,就不会有僵屍進程
学会了 SIG_IGN 一个,谢谢楼主!
原来都是在 SIGCHLD 的 handler 里 while ( 1 ) 调用 wait4 直到返回 -1 的 ……
无论是3还是4的处理方法,都是和系统的实现有关系的,比较安全可靠的方式还是自己做,而且使用waitpid多做几次,毕竟信号是不可靠的,而wait是可能阻塞的