说说Linux中的信号处理和僵尸进程的避免

发表于:2011-8-04 10:04

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:hinyunsin(CSDNblog)    来源:51Testing软件测试网采编

  什么僵尸进程

  这里简单说一下,详细的到网上搜一下就知道了:

  僵尸进程就是指子进程退出了,而父进程尚未退出,并且没有对子进程进行wait,致使子进程的资源得不到释放,依然占据在内存中,从而变成了像“僵尸”一样的进程(僵尸不能动,却占据着身体;进程不能执行了,却占据着内存等资源)。

  这种进程因为不再活动了,不会对信号进行处理,使用kill向它发送信号是没有用的,也就是它变成了杀不死的进程。

  wait是干什么的

  wait不是来打酱油的,看一下man手册的描述:

  All of these system calls are used to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal. In the case of a terminated child, performing a wait allows the system to release the resources associated with the child; if a wait is not performed, then the terminated child remains in a "zombie" state (see NOTES below).

  这段话的意思是说:wait是当前进程等待它的子进程的状态变化,并且能够取得子进程状态变化的一些信息。这种状态变化通常指的是子进程的结束或者恢复。当子进程结束的时候,wait函数将会告知系统释放该子进程的资源,如果没有使用wait函数,那么结束的子进程将会变成“僵尸”状态。

  这种僵尸状态会一直保持,直到父进程退出,被过继到老祖宗init(pid为1)进程,由init进程负责释放它们的资源。

  僵尸进程的避免

  网上搜一搜,基本上就是这样的三种方式:

  1、signal(SIGCHLD, SIG_IGN),忽略SIGCHLD信号,这样子进程结束后,就不需要父进程来wait和释放资源

  2、fork两次,第一次fork的子进程在fork完成后直接退出,这样第二次fork得到的子进程就没有爸爸了(真可怜。。。),它会被自动过继给老祖宗init进程,init会负责释放它的资源,这样就不会由“僵尸”产生了

  3、对子进程进行wait,释放它们的资源。但是父进程一般没工夫在那里守着,等着子进程的退出,所以,一般使用信号的方式来处理,在收到SIGCHLD信号的时候,再临时用wait操作来释放它们的资源。

  从个人角度,简单评价一下这三种方式:

  1、老爸不管儿子死活。父进程无法知晓子进程的退出情况。

  2、儿子自杀了,爷爷不管孙子。跟1一样,父进程无法知晓子进程的退出情况。

  3、老爸算是尽职了,儿子死了会给它火化(释放资源)。父进程可以知晓子进程的退出情况,不过处理比1和2麻烦。

  个人推荐第3种解决方法,这也引出了下面这样的一个问题。

  在《UNIX环境高级编程》10.8章节中有这样一段话:

  What happens if a blocked signal is generated more than once before the process unblocks the signal? POSIX.1 allows the system to deliver the signal either once or more than once. If the system delivers the signal more than once, we say that the signals are queued. Most UNIX systems, however, do not queue signals unless they support the real-time extensions to POSIX.1. Instead, the UNIX kernel simply delivers the signal once.

  这段话的意思是说:如果相同的信号在被在该进程解除对它的阻塞之前发生了多次,多数UNIX系统并不对该信号进行排队处理,也就是说,该信号将会被只递交一次。

  这就是Linux中信号处理有一个特点,那就是,同一个信号被递交多次,如果第一个信号还在处理,那么后面的信号都会被丢弃,而不会进入队列中等待处理。如果我们只是简单的对这个信号处理,必然会丢失对后面相同信号的处理。

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号