int wait(int *status);
The value returned by wait is the process ID of the child
process that terminated.
If the process that calls wait does not have any child
processes, wait returns a value of -1 immediately.
If the process that calls wait has one or more child
processes that has not yet terminated, then the calling process is suspended
by the kernel until one of its child process terminates.
When a child process terminates and wait returns, if
the status argument is not NULL, the value passed to exit by the
terminating child process is stored in the status variable.
Some additional info. is also returned by wait.
There are 3 conditions for which wait returns a process
ID as its return value.
1. A child process called exit.
2. a child process was terminated by a signal.
3. A child process was being traced and the process stopped.
This occurs when one process is tracing the execution of another process,
such as when a debugger is being used to step through a process.
see fig. 2.6
Signal numbers are greater than zero, otherwise it would
be impossible to distinguish between the three cases.
The core flag bit is one if the terminated process generated
a core file, otherwise it is zero.
As mentioned previously, a process has a single parent process, but it can have many child processes. The following steps are done by the kernel when a process exits.
If the parent process of the exiting process has called the wait system call, the parent process is notified that a child process has terminated (i.e. the wait system call returns to the parent). The parent process is passed the child's exit status (the child's argument to the exit function), if the parent's status argument was nonzero.
If the parent process of the exiting process has called the wait system call, the parent process is notified that a child process has terminated (i.e. the wait system call returns to the parent). The parent process is passed the child's exit status (the child's argument to the exit function), if the parent's status argument was nonzero.
If the parent process of the exiting process is not executing a wait, the terminating process is marked as a zombie process. A zombie process is one that has terminated, but its parent has not waited for it yet. The kernel releases all the resources being used by a zombie process (its memory, for e.g.) but has to at least maintain its exit status, until its parent waits for it.
The parent process ID of all the terminating process' child process is set to 1 (the init process).
If the process ID, process group ID, and terminal group ID fields of the terminating process are all equal, the hangup signal, SIGHUP, is sent to each process that has a process groupd ID equal to that of the terminating process.
What happens to the parent process ID of a child process when the parent process terminates beforre the child process? There are 2 possible scenarios to consider.
1. The child process terminates before the parent process.
This is normal condition when we are entering commands to an interactive
shell (assuming we don't logout before waiting for a command to complete).
a) If the parent process has already executed a wait,
then the wait returns to the parent process with the process ID of the
child that terminated.
b) If the parent process has not executed a wait, then
the child process becomes a zombie process as mentioned above.
2. The parent process terminates before its child processes.
This presents a problem, since the parent process IDs of any child processes
are no longer valid, once the parent terminates.
The way Unix handles this is to find all processes (active
or zombie) whose parent process ID equals the process ID of the terminating
process.
For these child processes that are about to be orphaned,
Unix sets their parent process ID to 1, the process ID of the init process.
The init process, therefore, becomes the parent process of any orphaned
processes.
The init process never terminates. Other than having
its parent process ID changed an executing child process is not aware that
its parent process has terminated.
When a process exits, a SIGCLD signal is generated in
the parent process. But by default, this signal is ignored.
Many programs are unaware of this signal. The purpose
of this signal is to allow the parent process to call wait to obtain the
exit status of its child process.
If a process knows that it will spawn child processes,
this is one technique to prevent its children from becoming zombies.
As mentioned earlier, if the parent does not wait for
a child process that has terminated, that child becomes a zombie, until
the parent also terminates. In some system (in most cases Unix system V)
allows a process to prevent any of its child processes from becoming zombies.
To do this, the parent has to execute
signal(SIGCLD, SIG_IGN);
to ignore this signal. This tells the kernel that the process is not interested in the exit status of its children. From this point on, the kernel will not generate zombie processes from the children of this process.