Can a parent process determine its child's status ?

Ray Ward ray at ctbilbo.UUCP
Fri Feb 23 04:40:48 AEST 1990


In article <5090.25e135aa at mva.cs.liv.ac.uk> adh at mva.cs.liv.ac.uk writes:
>Does anyone know how a parent process can determine the status of one
>of its children if it *hasn't* executed a wait ? It could arrange to 
>catch a SIGCLD signal, but if the parent had several children it
>wouldn't know which one had sent it the SIGCLD ... would it ?
>
>My reason for asking is as follows: I need to write a program which
>starts several children and reads from their respective stdout's via
>pipes. The children are executing simultaneously, so the parent uses
>non-blocking reads, polling each pipe to see if anything has arrived.
>Unfortunately, a call to 'read' returns zero if the child hasn't
>sent any new data *OR* if the child has terminated so the parent cannot
>distinguish between EOF on a pipe and a pipe that temporarily has no
>data in it.

You have pointed out one of the areas that needs improvement for
real time applications, among others.  How does one get complete
status information on a process, running or not, etc., without
awkward programming contortions?  There is no easy way.

Some information can be obtained quickly.  If you want to know if
the pid is still valid ( which hopefully means the child process is
still active ), use "kill( pid, 0 );".  The "0" is the null signal.
When kill is called with the null signal, only error checking is
performed, and the error checking boils down to seeing if the pid
is valid.

To find out which child died, you must keep a record of the children's
pids as they are forked.  The fork call will return the child's pid
to the parent.  Keep these in an array or list with something that
will identify the individual child (maybe only the array index).
Set up a handler for SIGCLD.  When SIGCLD is received, issue calls
to kill() with the null signal and see how many children are dead.

The reason for the list and the calls to kill() is that SIGCLD is
a bit, not a queue.  If two or more children were to die almost at
once, before your signal handler was invoked by the kernel, you might
miss one.  And you don't want to call wait() twice if only one child
has died.  Update the list of child pids.

Call wait().  Since at least one child has died, wait() will return
immediately with the pid of the child that died and either the code
the child passed to exit() or the number of the signal that killed it.
Call wait() once for each child that has died since the last SIGCLD.
The dead child is a zombie until you call wait() and takes up space
in the kernel's process tables, so be sure to call wait().

If you have the luxury of time, the ps command can be issued to the
shell with a system() call.  A la:  "system("ps -ef > uniquefile");
This file can be read and searched for the pid and the status information
parsed.  Why this isn't simply returned to the calling process in a 
process status structure I don't know.  

Good luck!


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Ray Ward                                          Email:  uunet!ctbilbo!ray  
Voice:  (214) 991-8338x226, (800) 331-7032        Fax  :  (214) 991-8968     
=-=-=-=-  There _are_ simple answers, just no _easy_ ones. -- R.R. -=-=-=-=



More information about the Comp.unix.questions mailing list