What is Zombie Process?
A zombie process or defunct process is a process that has completed execution (via the exit system call) but still has an entry in the process table. This occurs for the child processes, where the entry is still needed to allow the parent process to read its child's exit status. Once the exit status is read via the wait system call, the zombie's entry is removed from the process table and said to be "reaped". A child process always first becomes a zombie before being removed from the resource table.
In most cases, zombies are immediately waited on by their parents and then reaped by the system under normal system operation. Processes that stay zombies for a long time are generally an error and cause a resource leak, but they only occupy the process table entry.
In the term's metaphor, the child process has died but has not yet been reaped. Also, unlike normal processes, the kill command does not affect a zombie process.
Zombie processes should not be confused with orphan processes. An orphan process is a process that is still executing, but whose parent has died. When the parent dies, the orphaned child process is adopted by init (process ID 1). When orphan processes die, they do not remain as zombie processes; instead, they are waited on by init. The result is that a process that is both a zombie and an orphan will be reaped automatically.
How Zombie Process Works?
In an operating system, a zombie process works in the following way:
Let's see an example of a zombie process.
Output: It gives the following output, such as:
parent9 Child3 Child4 Child2 Child5 Child1 Child6 Child0 Child7 Child8 Child9 // there is a pause here parent8 parent7 parent6 parent5 parent4 parent3 parent2 parent1 parent0
In the first loop, the original (parent) process forks 10 copies of itself. Each of these child processes prints a message, sleep, and exits. All of the children are created at essentially the same time since the parent is doing very little in the loop, so it's somewhat random when each of them gets scheduled for the first time, thus the scrambled order of their messages.
During the loop, an array of child process IDs is built. There is a copy of the pids array in all 11 processes, but it is only complete in the parent. The copy in each child will be missing the lower-numbered child PIDs and have zero for its own PID.
The second loop executes only in the parent process and waits for each child to exit. It waits for the child who slept 10 seconds, and all the others have long since exited, so all of the messages (except the first) appear quickly. There is no possibility of random ordering here since a loop in a single process drives it. The parent could continue into the second loop before any of the child's processes could start. This again is just the random behavior of the process scheduler - the "parent9" message could have appeared anywhere in the sequence before "parent8".
Child0 through Child8 spend one or more seconds in this state, between the time they exited and the time the parent did a waitpid() on them. The parent was already waiting on Child9 before it exited so that one process spent essentially no time as a zombie.
Dangers of Zombie Processes
Zombie processes don't use any system resources, but they do retain their process ID. If there are a lot of zombie processes, then all the available process IDs are monopolized by them. This prevents other processes from running as there are no process IDs available.
Zombie processes also indicate an operating system bug if their parent processes are not running anymore. This is not a serious problem if there are a few zombie processes, but this can create issues for the system under heavier loads.
Preventions to Zombie Process
We need to prevent creating the Zombie process because there is one process table per system and the size of the process table is finite. If too many zombie processes are generated, then the process table will be full. The system will not generate any new process, and then the system will come to a standstill. Hence, we need to prevent the creation of zombie processes. Here are the different ways in the creation of the zombie can be prevented, such as:
1. sing wait() system call
When the parent process calls wait(), after creating a child, it will wait for the child to complete and get their exit status. The parent process is suspended (waits in a waiting queue) until the child is terminated. It must be understood that during this period, the parent process does nothing, just wait.
2. By ignoring the SIGCHLD signal
When a child is terminated, a corresponding SIGCHLD signal is delivered to the parent. If we call the 'signal(SIGCHLD,SIG_IGN)', then the system ignores the SIGCHLD signal, and the child process entry is deleted from the process table. Thus, no zombie is created. However, in this case, the parent cannot know about the exit status of the child.
3. By using a signal handler
The parent process installs a signal handler for the SIGCHLD signal. The signal handler calls wait() system call within it. In this scenario, when the child is terminated, the SIGCHLD is delivered to the parent. On receipt of SIGCHLD, the corresponding handler is activated, which calls the wait() system call. Hence, the parent immediately collects the exit status, and the child entry in the process table is cleared. Thus no zombie is created.
How to Kill Zombie Processes?
Zombie processes can be killed by sending the SIGCHLD signal to the parent using the kill command. This signal informs the parent process to clean up the zombie process using the wait() system call. This signal is sent with the kill command. It is demonstrated as follows:
In the above command, the pid is the process ID of the parent process.
What is SIGHLD Signal?
SIGCHLD is a signal of UNIX and UNIX-like systems. The code value of siginfo_t is as follows: