Zombie Processes
The operating system maintains a table that associates every process, by means of its process identifier (generally referred to as "pid") to the data necessary for its functioning. During a process's lifetime, such data might include memory segments designated to the process, the arguments it's been invoked with, environment variables, counters about resource usage, user-id, group-id and group set, and maybe other types of information.
When a process terminates its execution, either by calling exit (even if implicitly, by executing a return command from the main function) or by receiving a signal that causes it to terminate abruptly, the operating system releases most of the resources and information related to that process, but still keeps the data about resource utilization and the termination status code, because a parent process might be interested in knowing if that child executed successfully (by using standard functions to decode the termination status code) and the amount of system resources it consumed during its execution.
By default, the system assumes that the parent process is indeed interested in such information at the time of the child's termination, and thus sends the parent the signal SIGCHLD to alert that there is some data about a child to be collected. Such collection is done by calling a function of the wait family (either wait itself or one of its relatives, such as waitpid, waitid or wait4). As soon as this collection is made, the system releases those last bits of information about the child process and removes its pid from the process table. However, if the parent process lingers in collecting the child's data (or fails to do it at all), the system has no option but keep the child's pid and termination data in the process table indefinitely.
Such a terminated process process whose data has not been collected is called a zombie process, or simply a zombie, in the UNIX parlance (in a possibly humorous analogy that dubs the terminated process as "no longer alive" or "dead" -- since it has really ceased functioning --, and a lingering dead process still "incarnated" in the "world of the living" processes—the process table—is therefore actually "undead", or "zombie").
Zombie processes might pose problems on systems with limited resources or that have limited-size process tables, as the creation of new, active processes might be prevented by the lack of resources still used by long lasting zombies.
It is, therefore, a good programming practice in any program that might spawn child processes to have code to prevent the formation of long lasting zombies from its original children. The most obvious approach is to have code that calls wait or one of its relatives somewhere after having created a new process. If the program is expected to create many child processes that may execute assynchronously and terminate in an unpredictable order, it is generally good to create a handler for the SIGCHLD signal, calling one of the wait-family function in a loop, until no uncollected child data remains. It is possible for the parent process to completely ignore the termination of its children and still not create zombies, but this requires the explicit definition of a handler for SIGCHLD through a call to sigaction with the special option flag SA_NOCLDWAIT.
Read more about this topic: Parent Process
Famous quotes containing the word processes:
“Our bodies are shaped to bear children, and our lives are a working out of the processes of creation. All our ambitions and intelligence are beside that great elemental point.”
—Phyllis McGinley (19051978)