Reputation: 245
In the Book "Advanced Programming in Unix Environment", section wait and waitpid says:
waitpid function doesn't wait for the child that terminates first; it has a number of options that control which process it waits for.
I was reading this as if the child process exit first and the parent process hasn't called the waitpid
function, the child process won't be waited and will stay as a zombie process after quit.
So I wrote some code to test:
int main() {
pid_t pid = fork();
if (pid == 0) {
// child process
printf("Child Process ID: %d \n", getpid());
printf("Child Process Quit\n");
exit(0);
} else {
// parent
sleep(5);
printf("Parent Process ID: %d \n", getpid());
printf("Wait child %d ...\n", pid);
int status;
waitpid(pid, &status, 0);
printf("waitpid called\n");
sleep(5);
}
return 0;
}
The program first print out "Child Process ID" and "Child Process Quit", while the parent process is still sleeping, in another terminal window, if I use ps -el | grep 'Z'
, I am able to see this child process is <defunct>
(zombie).
Then 5 seconds later, as long as the parent process called waitpid
, in another terminal window, use ps -el | grep 'Z'
won't show the zombie child process any more, so it means the child process has been waited and not a zombie any more.
So seems the parent process can always wait for a child process with waitpid
, so how do I interpret this "waitpid function doesn't wait for the child that terminates first"?
Upvotes: 1
Views: 871
Reputation: 755036
If you complete the quotation (as it is now completed in the question), you see that waitpid()
is more flexible (than wait()
).
The POSIX specification says:
The pid argument specifies a set of child processes for which status is requested. The
waitpid()
function shall only return the status of a child process from this set:
If pid is equal to
(pid_t)-1
, status is requested for any child process. In this respect,waitpid()
is then equivalent towait()
.If pid is greater than 0, it specifies the process ID of a single child process for which status is requested.
If pid is 0, status is requested for any child process whose process group ID is equal to that of the calling process.
If pid is less than
(pid_t)-1
, status is requested for any child process whose process group ID is equal to the absolute value of pid.
So, as the quote says, waitpid()
doesn't always (only) wait for the first child to die; you can select much more precisely which child or children you are interested in. Additionally, you have options like WNOHANG
that mean that the function returns if there is no child that has died that meets the criterion (but there's at least one process that would meet the criterion). You get a different status if there are no children that meet the criteria.
Upvotes: 1