If I fork
a child process, and the child process exits before the parent calls waitpid
, then is the exit status information that is set by waitpid
still valid? If so, when does it become not valid; i.e., how do I ensure that I can call waitpid
on the child pid and continue to get valid exit status information after an arbitrary amount of time, and how do I "clean up" (tell the OS that I am no longer interested in the exit status information for the finished child process)?
I was playing around with the following code, and it appears that the exit status information is valid for at least a few seconds after the child finishes, but I do not know for how long or how to inform the OS that I won't be calling waitpid
again:
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid < 0) {
fprintf(stderr, "Failed to fork\n");
return EXIT_FAILURE;
}
else if (pid == 0) { // code for child process
_exit(17);
}
else { // code for parent
sleep(3);
int status;
waitpid(pid, &status, 0);
waitpid(pid, &status, 0); // call `waitpid` again just to see if the first call had an effect
assert(WIFEXITED(status));
assert(WEXITSTATUS(status) == 17);
}
return EXIT_SUCCESS;
}
Returned value If successful, waitpid() returns a value of the process (usually a child) whose status information has been obtained. If WNOHANG was given, and if there is at least one process (usually a child) whose status information is not available, waitpid() returns 0.
You can get the exit status of the child via the first argument of wait() , or the second argument of waitpid() , and then using the macros WIFEXITED and WEXITSTATUS with it. waitpid() will block until the process with the supplied process ID exits.
The waitpid() function allows the calling thread to obtain status information for one of its child processes. The calling thread suspends processing until status information is available for the specified child process, if the options argument is 0.
It is known that fork() system call is used to create a new process which becomes child of the caller process. Upon exit, the child leaves an exit status that should be returned to the parent. So, when the child finishes it becomes a zombie. Whenever the child exits or stops, the parent is sent a SIGCHLD signal.
Yes, waitpid
will work after the child has exited. The OS will keep a child process' entry in the process table (including exit status) around until the parent calls waitpid
(or another wait
-family function) or until the parent exits (at which point the status is collected by the init
process). This is what a "zombie" process is: a process that has exited by is still resident in the process table for exactly this purpose.
The process' entry in the table should go away after the first call to waitpid
. I suspect the reason that in your example you seem to be able to call waitpid
twice is simply because waitpid
will not modify the status
argument if pid
no longer exists. So the first call should be working and filling in status
, and the second call should be returning an error code and not changing status
. You can verify this by inspecting the return values of the waitpid
calls and/or using two different status
variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With