很不幸地,对于死掉的子 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只有一个。