At the time each process exits, the kernel frees all resources of the process, including open files, memory used, and so on. however , it still retains certain information, which mainly refers to the Process Control block information (including process number, exit status, run time, etc.). Until the parent process obtains its state through wait () or waitpid (), and releases it (see "Waiting for process end" for specific usage). This can lead to a problem, if the process does not call wait () or waitpid (), then the reserved piece of information will not be released, its process number will always be occupied, but the system can use the process number is limited, if a large number of zombie process generated, The system cannot produce a new process because no process number is available. This is the threat to the zombie process and should be avoided .
The child process has run end, and the parent process does not call the wait () or waitpid () function to reclaim the child process's resources as a result of the child process becoming a zombie process .
The zombie process test program is as follows:
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h>int main (int argc, Char *argv[]) { pid_t pid; PID = fork ()//Create Process if (PID < 0) {//Error perror ("Fork Error:"); Exit (1); } else if (0 = = pid) {//subprocess printf ("I am child process. I am exiting.\n ");p rintf (" [son id]:%d\n ", Getpid ()); Exit (0); } else if (PID > 0) {//parent process//parent process does not call Wati () or Watipid () sleep (1);//guarantees that the child process first runs printf ("I am father process. I'll sleep The seconds\n ");p rintf (" [Father ID]:%d\n ", Getpid ()); while (1); Do not let the parent process exit} return 0;}
Operation Result:
At the terminal knock:Ps-ef | grep Defunct, the defunct in the back angle brackets is the zombie process.
We start another terminal to see the status of the process and what are the zombie processes:
Or: With PS-E
1) The simplest way, the parent process waits for the child process to end through functions such as wait () and waitpid (), but this causes the parent process to hang. For specific usage, see Process Control: End process, wait for process to end.
2) If the parent process has to deal with a lot of things, cannot hang, through the signal () function artificial processing signal SIGCHLD, as long as there is a child process exit automatically call the specified callback function, because the child process is finished, the parent process will receive the signal SIGCHLD, in its callback function can call wait () or Waitpid () recovery. For more detailed usage of the signal, see "signal Interrupt Handling".
The test code is as follows:
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < Signal.h>void sig_child (int signo) { pid_t pid; To handle the zombie process, 1 represents waiting for any child process, Wnohang represents not blocking while (PID = Waitpid ( -1, NULL, Wnohang)) > 0) {printf ("Children%d terminated. \ n ", pid);}} int main () { pid_t pid; Create capture subprocess exit signal//As long as the child process exits, trigger SIGCHLD, automatically call Sig_child () signal (SIGCHLD, sig_child); PID = fork ()//Create Process if (PID < 0) {//Error perror ("Fork Error:"); Exit (1); } else if (PID = = 0) {//Sub-process printf ("I am child process,pid ID%d.i am exiting.\n", getpid ()); Exit (0); } else if (PID > 0) {//Parent process sleep (2);//Ensure that the child process first runs printf ("I am father, I am exited\n\n"); System ("Ps-ef | grep defunct "); See if there is a zombie process} return 0;
Operation Result:
3) If the parent process does not care about when the child process ends, then the kernel can be notified with signal (SIGCHLD, sig_ign) , and the parent process ignores this signal, so the kernel is recycled after the child process is over. And no longer sends a signal to the parent process. For more detailed usage of the signal, see "signal Interrupt Handling".
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < Signal.h>int Main () { pid_t pid; Ignore signal of child process exit signal//Then after the child process is finished, the kernel recycles and no longer sends a signal to the parent process signal (SIGCHLD, sig_ign); PID = fork ()//Create Process if (PID < 0) {//Error perror ("Fork Error:"); Exit (1); } else if (PID = = 0) {//Sub-process printf ("I am child process,pid ID%d.i am exiting.\n", getpid ()); Exit (0); } else if (PID > 0) {//Parent process sleep (2);//Ensure that the child process first runs printf ("I am father, I am exited\n\n"); System ("Ps-ef | grep defunct "); See if there is a zombie process} return 0;
Operation Result:
4) There are some tricks, that is, fork () two times, the parent process fork () a child process, and then continue to work, the child Process fork () after a grandchild process exit, then the Sun process is init takeover, after the end of the sun process, the init (1th process) will be recycled. But the recycling of the sub-process to do it yourself. "Advanced Programming for UNIX Environment" section 8.6 says very detailed. The principle is to make the child process an orphan process, so that its parent process becomes the init process (process 1th), which can handle the zombie process through the init process (Process # 1th). For more details, see the orphan process of the special process.
The source code is as follows:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h>int main () { pid_t pid; Create the first child process pid = fork (); if (PID < 0) {//Error perror ("Fork Error:"); Exit (1); } else if (PID = = 0) {//Sub-process //Sub-process re-create child process printf ("I am the first children process.pid:%d\tppid:%d\n", Getpid (), Getppid () ); PID = fork (); if (PID < 0) { perror ("Fork Error:"); Exit (1); } else if (PID = = 0) {///child process//sleep 3s guarantees that the following parent process exits, so that the current child process's father is the init process sleep (3);p rintf ("I am the second child process.pid:%d\tppid :%d\n ", Getpid (), Getppid ()); exit (0);} else if (PID >0) {//parent process exits printf ("First procee is exited.\n"); Exit (0); } } else if (PID > 0) {//parent process//parent process exits the first child process, reclaims its resource if (Waitpid (PID, NULL, 0)! = pid) {perror ("Waitepid error:"); exit (1);} Exit (0);} return 0;}
Operation Result:
All Source Downloads: http://download.csdn.net/download/lianghe_work/8999129
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.