The child only becomes a zombie if it ends and the parent doesn't call wait*()
as long as itself lives on.
In the moment the parent also ends the child is reaped by the init
process which will take care to call wait*()
on the child, so it will finally end and with this leave the zombie state and disappears from the process list.
To provoke the child created in your example code to become a zombie modify the code for example as follows:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p = fork();
if (p != 0)
{
waitpid(p, NULL, 0); /* See if the child already had ended. */
sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */
pause(); /* Suspend main task. */
}
else
{
sleep(3); /* Just let the child live for some tme before becoming a zombie. */
}
return 0;
}
Due to the two following facts:
- the child sleeps for 3s so the parent's call to
waitpid()
most probably will always fail - the default handling of
SIGCHLD
is to ignrore it.
the code above in fact is the same as:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p = fork();
if (p != 0)
{
pause(); /* Suspend main task. */
}
else
{
sleep(3); /* Just let the child live for some tme before becoming a zombie. */
}
return 0;
}