如何确保`waitpid(-1,&stat,WNOHANG)`收集所有子进程

q09*_*987 3 c++ posix network-programming process

从Unix网络编程Vol1第三版第5.10节提取等待和waitpid功能

#include    "unp.h"    
void
sig_chld(int signo)
{
    pid_t   pid;
    int     stat;    
    while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated\n", pid);
    }
    return;
}

...
// in server code
Signal(SIGCHLD, sig_chld); // used to prevent any zombies from being left around
...

..
// in client code
The client establishes five connection with the server and then immediately exit
...
Run Code Online (Sandbox Code Playgroud)

引用waitpid:

回报价值

waitpid():成功时,返回状态已更改的子进程ID; 如果指定了WNOHANG并且存在由pid指定的一个或多个子(ren),但尚未更改状态,则返回0.出错时,返回-1.

根据上述文件,如果目前没有子进程终止,waitpid将返回0.如果我理解正确,这将导致函数sig_chldwhile语句中断.

问题>因此,我们如何保证此信号处理程序可以确保收集所有已终止的子进程?

Duc*_*uck 6

while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated\n", pid);
Run Code Online (Sandbox Code Playgroud)

如果您没有要处理的孩子,您将不会在信号处理程序中.循环是因为当你在处理程序本身时,第二个或第三个孩子可能已经改变或终止发送不会排队的SIGCHLD.因此,循环实际上可以防止你错过那些可能死去的孩子.当目前没有更多的孩子被收获时,它将返回0或错误输出-1(ECHILD).