引言
众所周知,子进程退出后(不管是正常还是异常退出),其父进程需要通过wait或waitpid来回收子进程的一些资源。回收是没有疑义的,但是父进程在哪儿回收,以什么方式回收,却影响着设计思路和效率。
一般的回收机制。
一般来说,都喜欢在fork后,父进程分支直接调用wait来等待子进程退出,并回收其资源。如apue上的例子
上面程序是能保证在子进程退出后,父进程来回收。但同时也存在一些不足之处:
1、必须顺序回收,即fork一次,回收一次;
2、每次回收的是阻塞模式。
改进版回收机制
由于一般的回收机制,异步性太差,效率很低,因此就有了一些改进措施。
1、将创建的子进程连接起来,形成链表。这个步骤是必须的,它可以加强对子进程的管理(这些不在讨论之列)。
2、提供接口回收子进程。
这样做确实可以达到异步的效果,但是也存在问题:父进程什么时候去调用回收接口。
如果调用阻塞模式的话,只要子进程不退出,就会导致父进程一直挂起在那儿;
如果调用非阻塞模式的话,但调用时机不对,即此刻子进程没有退出,那么父进程就回收不到资源。如此则父进程需要周期性的扫描子进程队列,以保证所有子进程被回收。
因此此种机制应当用在功能比较明确的地方,即知晓子进程何时退出,譬如popen和pclose。
信号版回收机制
那么有没有一种机制,子进程退出时,父进程能够比较实时的被通知到?答案肯定是有。
首先我们来看一下apue关于wait章节的开场白
When a process terminates, either normally or abnormally, the kernel notifies the parent by sending the SIGCHLD signal to the parent.
当一个进程,不管它是正常退出还是异常退出时,内核都会通过发送信号SIGCHLD到其父进程的方式来通知其父进程。
这是我们采取信号回收的原理所在,其步骤为:
1、建立信号处理handle
signal(SIGCHLD, sigchld_handler);
2、信号处理handle的实现
这里有几点需要解释:
1)这里采用waitpid,说明不能阻塞;
2)-1表示回收任意子进程;
3)WNOHANG表示不阻塞。
实例
个人写了一个例子:定义了一个命令数组,每个命令由一个子进程去执行,同时父进程在信号处理hanlde中回收子进程。
详见我的资源
转载请说明出处。