Causes and solutions for zombie Processes

Source: Internet
Author: User

Causes and solutions for zombie Processes

Generation of zombie processes:

When a process creates a sub-process, its operation is asynchronous. That is, the parent process cannot predict when the child process will end. If the child process is too busy to wait for wait, when the child process ends, will the status information at the end of the sub-process be lost? In this case, unix provides a mechanism to ensure that the parent process can obtain the information at the end of the Child process as long as it wants to know the information of the child process.

This mechanism is: when each process exits, the kernel releases all resources of the process, including open files and memory occupied. However, some information is retained (such as the running time of the process ID pid exit status ). The reserved information will not be released until the process calls wait/waitpid. This leads to a problem. If wait/waitpid is not called, the reserved information will not be released. For example, the process number is always occupied. However, the process number that the system can use is limited. If a large number of zombie processes are generated, the system will not have an available process number and the system will not be able to create a process. So we should avoid zombie processes.


Here is a note. If the child process ends first and the parent process ends, that is, after the child process ends, the child process continues to run but does not call wait/waitpid, then the child process becomes a zombie process.


However, if the child process ends, that is, the parent process ends first, but does not call wait/waitpid to wait until the child process ends, the child process is still running, and the parent process has ended. Then there will be no zombie process. The system should scan all processes running in the current system at the end of each process to see if there are any sub-processes of this process that have just ended, there is init to take over it and become its parent process.


In the same case where a zombie process is generated, that is, when the child process ends but the parent process continues to run (wait/waitpid is not called), if the parent process terminates abnormally, the child process is automatically taken over by init. Then it is no longer a zombie process. It should be that the intit will discover and release the resources it occupies. (Of course, if the progress table is larger, init finds that it takes over the zombie process, and the process slows down. So before init finds them, the zombie process still consumes system resources)



Let's first discuss the situation of parent Process Termination:


For example, this code. Let the sub-process print five statements in a loop. The parent process prints three statements in a loop. And call wait () in the parent process to wait for the completion of the Child process //


#include#include#include#include#includeint main(){       int count;       pid_t pid;       char *message;        printf("fork program starting\n");        pid=fork();       switch(pid)       {                  case -1:perror("forkerror");                        exit(EXIT_FAILURE);                        break;                case 0 :message="This isthe children";                        count=10;                        break;                default:message="This isthe parent.";                        count=3;                        break;        }         for(;count>0;count--)       {                 printf("%s\n",message);                sleep(1);       }         if(pid)                wait((int *)0);       if(pid)                printf("Father programDone.\n");       else                printf("Child ProgramDnoe\n");       exit(0);    }



Let's run the program in the background and run the ps command to view the process status.


We can see from the output

The first line shows that the pid of the process we run is 2734.

Ps output shows that there is a 2735 sub-process,

The parent process does not end after three cycles, but waits until the child process ends.

No zombie process is generated here



If we don't wait until the process ends

Set if (pid)

Comment out wait (int *) 0)

The following output is generated:

From the first line, we can see that the pid of the program we run is 2804.

Pid 2805 in Ps output is the created sub-process. We can run the ps command to check whether the parent process ends after it ends (wait is not called, so the parent process ends first. Therefore, the parent process of 2805 is changed to 1 (init pid). Because 2804 is over, the child process of 2805 is taken over by init, and no zombie process is generated here.


Now let's analyze the situation of sub-Process Termination:

The following program is provided:


#include#include#include#include int main(){       int count;       char *message;       pid_t pid;        pid=fork();       switch(pid)       {                  case -1:                        perror("forkerror");                        exit(EXIT_FAILURE);                case 0:message="This isthe child.";                        count=5;                        break;                default:message="This isth parent.";                        count=10;                       break;       }         for(;count>0;count--)       {                 printf("%s\n",message);                sleep(2);       }          if(pid)                printf("Father programDone.\n");       else                printf("Child prigramDone\n");       exit(EXIT_SUCCESS); }

The code here is slightly changed. We only changed the printing times of the Parent and Child processes.


In addition, in the parent process, we do not call wait/waitpid to release some information about the child process.


When the child process ends but the parent process is not completed, we can view the process information.

In the first line, we can see that the pid of the program we run is 2874, and its sub-process is 2875 in ps output.

We noticed that the process with pid 2875 was a zombie process. If the main thread runs for a long enough time, the zombie process will always exist and occupy some system resources.


We have learned the cause of the botnet process, so how can we avoid it.


If the parent process is not very busy, we can directly call wait/waitpid to wait for the child process to end. Of course, this will cause the parent process to be suspended. For example, in the first case (the parent process loops three times, the child process loops five times, the child process ends first, and the parent process calls wait to wait for the child process) the parent process does not end after the loop ends, but is suspended and waits for the child process to end.


However, if the parent process is busy. We do not want the parent process to be suspended until the child process ends.

Then we can use the signal function sigaction to set the wait processing function for SIGCHLD. After the process ends, the parent process will receive the signal of the child process ending. And call wait to reclaim sub-process resources.

Here is a routine.



#include#include#include#include#include#includevoid fun_act(int sig){       wait((int *)0);}int main(){       int count;       char *message;       pid_t pid;        struct sigaction act;       act.sa_handler=fun_act;       sigemptyset(&act.sa_mask);       act.sa_flags=0;        pid=fork();       switch(pid)       {                  case -1:                        perror("forkerror");                        exit(EXIT_FAILURE);                 case 0:message="This isthe child.";                        count=5;                        break;                                           default:message="This isth parent.";                        count=10;                        break;       }if(pid)               if(sigaction(SIGCHLD,&act,0)==-1)                {                        perror("Settingsignal failed.");                        exit(1);                }       for(;count>0;count--)       {               printf("%s\n",message);                sleep(1);       }       if(pid)                printf("Father programDone.\n");       else                printf("Child prigramDone\n");       exit(EXIT_SUCCESS); }




We used ps to view the sub-process before it ends, and then checked it once.

From the output, we can see that the sub-process with a pid of 2949 is normal and has not produced any zombie process. After the child process is completed, the parent process receives the message and calls wait to recycle the child process resources. This avoids zombie processes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.