Open In App

Zombie Processes and their Prevention

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Zombie state: When a process is created in UNIX using fork() system call, the parent process is cloned. If the parent process calls wait() system call, then the execution of the parent is suspended until the child is terminated. At the termination of the child, a ‘SIGCHLD’ signal is generated by the kernel which is delivered to the parent. Parent, on receipt of ‘SIGCHLD’ reads the status of the child from the process table. 

Prerequisites: fork() in C, Zombie Process

Even though the child is terminated, there is an entry in the process table corresponding to the child where the status is stored. When the parent collects the status, this entry is deleted (or we also say the parent reaped its child process) . Thus, all the traces of the child process are removed from the system. If the parent decides not to wait for the child’s termination and executes its subsequent task, then at the termination of the child, the exit status is not read. Hence, there remains an entry in the process table even after the termination of the child. This state of the child process is known as the Zombie state. 

C




// A C program to demonstrate working of
// fork() and process table entries.
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
 
int main()
{
    int i;
    int pid = fork();
 
    if (pid == 0)
    {
        for (i=0; i<20; i++)
            printf("I am Child\n");
    }
    else
    {
        printf("I am Parent\n");
        while(1);
    }
}


Output : 

zombie1_1

Now check the process table using the following command in the terminal
$ ps -eaf

zombie1_2

Here the entry [a.out] defunct shows the zombie process.

Why do we need to prevent the creation of the Zombie process? 
There is one process table per system. The size of the process table is finite. If too many zombie processes are generated, then the process table will be full. That is, the system will not be able to generate any new process, then the system will come to a standstill. Hence, we need to prevent the creation of zombie processes.
 

Different ways in which the creation of Zombie can be Prevented

1. Using wait() system call: When the parent process calls wait(), after the creation of a child, it indicates that, it will wait for the child to complete and it will reap the exit status of the child. 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.

C




// A C program to demonstrate working of
// fork()/wait() and Zombie processes
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
 
int main()
{
    int i;
    int pid = fork();
    if (pid==0)
    {
        for (i=0; i<20; i++)
            printf("I am Child\n");
    }
    else
    {
        wait(NULL);
        printf("I am Parent\n");
        while(1);
    }
}


(Point 2. is wrong and doesn’t prevent zombie creation,  its the job of parent process to remove the child process from process list and is not done by the kernel, infact SIG_IGN is the default handler for SIGCHLD signal to the parent process).

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 SIGCHLD signal is ignored by the system, 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.

C




// A C program to demonstrate ignoring
// SIGCHLD signal to prevent Zombie processes
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
 
int main()
{
    int i;
    int pid = fork();
    if (pid == 0)
        for (i=0; i<20; i++)
            printf("I am Child\n");
    else
    {
        signal(SIGCHLD,SIG_IGN);
        printf("I am Parent\n");
        while(1);
    }
}


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 terminated, the SIGCHLD is delivered to the parent. On receipt of SIGCHLD, the corresponding handler is activated, which in turn calls the wait() system call. Hence, the parent collects the exit status almost immediately and the child entry in the process table is cleared. Thus no zombie is created.

C




// A C program to demonstrate handling of
// SIGCHLD signal to prevent Zombie processes.
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
 
void func(int signum)
{
    wait(NULL);
}
 
int main()
{
    int i;
    int pid = fork();
    if (pid == 0)
        for (i=0; i<20; i++)
            printf("I am Child\n");
    else
    {
        signal(SIGCHLD, func);
        printf("I am Parent\n");
        while(1);
    }
}


Output:

zom_final

Here no any [a.out] defunct i.e. no Zombie process is created.

4. Double fork: This involves creating a grandchild process which is then orphaned by the parent process. This ensures that the grandchild process is inherited by the init process, which reaps it automatically. This prevents the creation of a zombie process.

C




// A C program to demonstrate double fork
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int main() {
    int status;
    pid_t pid = fork();
 
    if (pid == 0) {
        pid_t child_pid = fork();
        if (child_pid == 0) {
            printf("I am grandchild\n");
            exit(0);
        }
        else {
            printf("I am child\n");
            exit(0);
        }
    }
    else {
        wait(&status);
        printf("I am parent\n");
        while(1);
    }
}


5. Using the waitpid() system call: This system call is similar to the wait() system call, but it allows the parent process to wait for a specific child process to terminate. This way, the parent can collect the exit status of the child and prevent the creation of a zombie process.

C




// A C program to demonstrate the use of waitpid()
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
 
int main()
{
    int i;
    int pid = fork();
    if (pid == 0){
        for (i=0; i<20; i++)
        printf("I am Child\n");
    }
    else
    {
        int status;
        waitpid(pid, &status, 0);
        printf("I am Parent\n");
        while(1);
    }
}


 



Last Updated : 29 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads