[ 永远的UNIX::UNIX技术资料的宝库 ]

首页 > 系统管理 > 其它 > 正文
要怎样才能避免在内存中留下zombie processes?
Steve Hayman (2001-04-19 11:33:05)
 很不幸地,对于死掉的子 process 应有的行为特性并没有办法做一般化,因 
 为这些特定/特定的机制会随著 Unix 的种类不同而有所差异。 

 首先,在各种 Unix 上面您都必需使用 wait() 来处理子 process。也就是 
 说,我还没看过有一种 Unix 会自动把结束的子 process 干掉,即使您不告 
 诉它该怎么做。 

 其次,在某些从 SysV 衍生的系统当中,如果您执行了 signal(SIGCHLD, 
 SIG_IGN)",(嗯,事实上应该是SIGCLD 而非SIGCHLD,但大多数新出 
 炉的 SysV 系统都会在表头档当中加上 #define SIGCHLD SIGCLD),那 
 么子 processes 都会自动被清除得乾乾净净,您什么事都不用做。看看这个 
 方式是否可行的最佳做法就是自己在机器上试试看。如果您想试著写出具可 
 携性的程式码,那么依赖这种特殊处理方式可能不是好主意。不幸的是,在 
 POSIX 并不允许您这样做;把 SIGCHLD 的行匦陨璩?nbsp;SIG_IGN 在 
 POSIX 当中并没有定义,所以如果您要让您的程式合乎 POSIX 的要求 
 时,您就不可以这样做。 

 那么怎样才算是 POSIX 的做法呢?如同前面所述,您必需设定一个 signal 
 的处理函数,然后让它去 wait。在 POSIX 当中 signal 处理函数是经由 
 sigaction 设定,由于您只对终止的子 process 感兴趣,而不是那些 stopped 
 的子 process,所以可以在 sa_flags 当中加上 SA_NOCLDSTOP。如果要 
 wait 子 process 而本身不因此被挡 (block),可以使用 waitpid()。第一 
 个参数必需是 -1 (代表 wait 任何 pid),第三个参数必需是 WNOHANG,这是 
 最具可携性的做法,也是可能会成为未来最具可携性的写法。 

 如果您的系统不支援 POSIX,那就有很多做法了。最简单的方式就是先试 
 试signal(SIGCHLD, SIG_IGN) 是否可行,可以的话那就好了。如果 
 SIG_IGN 无法用来强制自动收拾残骸,那么您就要自己写一个 signal 处理 
 函数来收拾残骸了。要写出一个适用于每一种 Unix 的 singal 处理函数来 
 做这件事是不容易的事,因为有下列不一致的地方: 
 
 在一些 Unix 中,一个或一个以上的子 process 死时,会呼叫 SIGCHLD 的 
 signal 处理函数。也就是说,如果你的 signal 处理函数只有一个 wait() 
 时,并不会把所有的子 process 都收拾乾净。不过还好,我相信这类的 
 Unix 都会有 wait3() 或 waitpid(),这两者都有可在 option 参数中使用 
 WNOHNAG 可用来检查是否有子 process 尚待收拾。所以在一个有 
 wait3()/waitpid() 的系统中,你可以一再重复使用 wait3()/waitpid() 
 以确定所有的子 process 都已收拾乾净W詈檬怯?nbsp;waitpid() 因为 
 它在 POSIX 标准中。 

 在一些 SysV-derived 的系统中,再 SIGCHLD 的 signal 处理函数结束后, 
 若还有子 process 等待清除,还是会产生 SIGCHLD signal。 因此,在大部 
 份的 SysV 系统中,在 signal 处理函数里可以假设要处理的 signal 只有一 
 个, 
(http://www.fanqiang.com)
    进入【UNIX论坛

相关文章

===更多相关===
 

★  樊强制作 欢迎分享  ★