Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How does waitpid() work?

167 views
Skip to first unread message

Khalid Ahmed

unread,
Oct 20, 1992, 5:19:01 PM10/20/92
to
Hi,

I'm trying to understand how the waitpid() call works. I've written
the following code which simply does a fork() and waits for
its child to die. As you can see from the output, the waitpid
fails. I've tried putting in a sleep() before I exit from
the child but this doesn't help.

This code seems to work fine on ULTRIX and SUNOS, but not on AIX3.2.
Also I've compiled with -D_BSD -lbsd.

It seems like the child dies before the parent calls waitpid(),
but I thought it (the child) just became a zombie until it is collected
by the waitpid.
Does anyone have any clues?

Thanks in advance

---------- PROGRAM ----------
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>

main()
{
int pid;
int status;

signal(SIGCHLD, SIG_IGN);

if (pid = fork()) {
printf("Parent: pid=%d childpid=%d \n",getpid(),pid);
if (waitpid(pid, &status, 0) < 0)
perror("waitpid fails");
else
printf("waitpid OK\n");
} else {
printf("Child: pid=%d\n",getpid());
exit(5);
}
}

----------OUTPUT--------------
Child: pid=19726
Parent: pid=15885 childpid=19726
waitpid fails: No child processes

-----------------------------------------------------------------------------------
Khalid Ahmed
Computer Science Research Institute
Univerisity of Toronto
Email: ahm...@white.toronto.edu
-----------------------------------------------------------------------------------

L. Scott Emmons

unread,
Oct 23, 1992, 11:53:04 AM10/23/92
to
In article <1992Oct20.1...@jarvis.csri.toronto.edu> ahm...@sys.toronto.edu (Khalid Ahmed) writes:
>It seems like the child dies before the parent calls waitpid(),
>but I thought it (the child) just became a zombie until it is collected
>by the waitpid.
>Does anyone have any clues?

Yes. It looks (though I didn't compile and run the program) that the
problem is not that the child exits to quickly, but that the parent
gets to waitpid() before the child process has even started up, thus
the error message "No child processes".

L. Scott Emmons
CableData Research Center
csusac.csus.edu!cdsac!scotte
KC6NFP

James R. Hamilton

unread,
Oct 25, 1992, 8:10:33 AM10/25/92
to
>Hi,
>
>I'm trying to understand how the waitpid() call works. I've written
>the following code which simply does a fork() and waits for
>its child to die. As you can see from the output, the waitpid
>fails. I've tried putting in a sleep() before I exit from
>the child but this doesn't help.
>
>This code seems to work fine on ULTRIX and SUNOS, but not on AIX3.2.
>Also I've compiled with -D_BSD -lbsd.
>
>It seems like the child dies before the parent calls waitpid(),
>but I thought it (the child) just became a zombie until it is collected
>by the waitpid.
>Does anyone have any clues?
>
>Thanks in advance
>
>---------- PROGRAM ----------
>#include <stdio.h>
>#include <signal.h>
>#include <sys/wait.h>
>
>main()
>{
> int pid;
> int status;
>
> signal(SIGCHLD, SIG_IGN);

This is the problem. Even though the default action for SIGCHLD is to
SIG_IGN it, setting the action explicitly to SIG_IGN is overloaded to
mean "that the process does not want to receive the SIGCHLD signal when
one of its child process dies, and does not want to have its wait calls
return because a child process is dead (just when no more child proc-
cesses exist, and on stopped child processes)" -- from man 2 signal.

Not bothering to call signal(2) or calling it with a SIG_DFL action
will do what you want.

>
> if (pid = fork()) {
> printf("Parent: pid=%d childpid=%d \n",getpid(),pid);
> if (waitpid(pid, &status, 0) < 0)
> perror("waitpid fails");
> else
> printf("waitpid OK\n");
> } else {
> printf("Child: pid=%d\n",getpid());
> exit(5);
> }
>}
>

--

James R. Hamilton inet: j...@jrh.gts.org
telephone: +1 416 493 4162 uunet: ...!uunet!jrh!jrh
Toronto, Canada bitnet: jrh%j...@uunet.uu.net

Jeff Peek

unread,
Oct 23, 1992, 10:59:37 AM10/23/92
to
The order of child death and parent calling wait are not the problem. See below.

>Does anyone have any clues?
>
>Thanks in advance
>
>---------- PROGRAM ----------
>#include <stdio.h>
>#include <signal.h>
>#include <sys/wait.h>
>
>main()
>{
> int pid;
> int status;
>
> signal(SIGCHLD, SIG_IGN);

Here is the culprit. By setting the action for SIGCHLD to ignore, the system
assumes the SysV behaviour and has all your exiting children cleaned up
immediately. Any following wait/waitpid/wait3 call will not return until all the
processes children have exited and then return ENOCHILD. So, although you compiled
for BSD, the overriding behaviour in this case in SysV.

>
> if (pid = fork()) {
> printf("Parent: pid=%d childpid=%d \n",getpid(),pid);
> if (waitpid(pid, &status, 0) < 0)
> perror("waitpid fails");
> else
> printf("waitpid OK\n");
> } else {
> printf("Child: pid=%d\n",getpid());
> exit(5);
> }
>}
>
>----------OUTPUT--------------
>Child: pid=19726
>Parent: pid=15885 childpid=19726
>waitpid fails: No child processes
>
>-----------------------------------------------------------------------------------
>Khalid Ahmed
>Computer Science Research Institute
>Univerisity of Toronto
>Email: ahm...@white.toronto.edu
>-----------------------------------------------------------------------------------


--
Jeff Peek
AIX Operating System Architecture -- IBM Personal Systems Programming
ran...@perelandra.austin.ibm.com VNET PEEK at AUSVM6 T/L 678-3913
Austin, TX

0 new messages