3

Extracted from Unix Network Programming Vol1 Third Edition Section 5.10 wait and waitpid functions

#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
...

Reference waitpid:

Return Value

waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified and one or more child(ren) specified by pid exist, but have not yet changed state, then 0 is returned. On error, -1 is returned.

Based on the above document, waitpid will return 0 if at the moment no child process has terminated. If I understood correctly, this will cause the function sig_chld break from the while statement.

Question> Thus how can we guarantee that this signal handler can make sure all terminated children processes are collected?

q0987
  • 34,938
  • 69
  • 242
  • 387

1 Answers1

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

You wouldn't be in the signal handler if you didn't have a child to handle. The loop is because while you are in the handler itself a 2nd or 3rd child could have changed or terminated sending SIGCHLDs that would not be queued. Thus the loop actually prevents you from missing those possible dead children. It will return 0 or error out with a -1 (ECHILD) when there are no more children to be reaped at the moment.

Duck
  • 26,924
  • 5
  • 64
  • 92