Orphan process: One parent process exits, and one or more of its child processes are still running, then those child processes will become orphans. The orphan process will be adopted by the INIT process (process number 1) and the Init process completes the state collection for them.
Zombie Process: A process uses fork to create a child process, and if the child process exits, and the parent process does not call wait or waitpid to get state information for the child process, the process descriptor of the child process is still stored in the system. This process is called a zombie process.
#include <stdio.h>#include <iostream>#include "unistd.h"#include "assert.h"#include <stdlib.h> int glob = 6; Char buf[] = "A write to Stdout\n",main (int argc, char* argv[]) {int var,pid_t pid, var = n,if (write (S) Tdout_fileno, buf, sizeof (BUF)-1)! = sizeof (BUF)-1) assert ("Write error"); printf ("Before fork\n"); PID = fork ()) < 0 ) {assert ("fork error");} else if (PID = = 0) {glob++; var++; printf ("Im child\n");} else{sleep]; printf ("Im father\n");} printf ("pid =%d, Glob =%d, var =%d\n", Getpid (), Glob, var
); Exit (0
);
}
After compiling the above piece of code on Linux, review the process PS aux immediately | grep test
You'll see that the process produced a zombie process
The reason for the zombie process to occur:
The parent process uses fork to produce a child process after the child process has finished executing, but its parent process has not yet disposed of it (getting information about terminating the child process, releasing the resources it still occupies), such a child process is a zombie process with a process state of Z
The above example explains:
The main process runs and then fork a child process, and then the child process executes the program normally, but the parent process does not get the child process after sleep, so the subprocess is dead at this time.
When the main process finishes sleep, the resource is freed, and its child processes are freed.
If the parent process exits abnormally, the child process is taken over by the INIT process (a process with PID 1), and then the INIT process continually polls his child for dead processes and kills them. But if its zombie process is more and more, the discovery process is slow, so avoid zombie processes.
Functions to view the state of a child process are: wait and waitpid
The differences between the two functions are:
After the parent process fork a child process, the parent process does not die, call wait, and the parent process blocks until one of his child processes exits (producing a zombie process), then captures the information of his child process and cleans up the child process (complete kill child process), if it is called Waitpid, The parent process does not block, that is, check the current have no own child process (there is a zombie process does not), if there is the aftercare, no, continue the parent process logic.
Ways to resolve Zombie processes:
Method 1: When the process exits, a signal is sent to the parent process.
#include <stdio.h>#include <iostream>#include "Unistd.h"#include "Assert.h"#include <stdlib.h>#include "sys/wait.h" int glob = 6; char buf[] = "A write to stdout\n"; voidForktest () {int var; pid_t pid; var = 88; if (Write (Stdout_fileno, buf, sizeof (BUF)-1)! = sizeof (BUF)-1) Assert ("Write error"); printf ("Before fork\n"); if (PID = fork ()) < 0{Assert ("fork error")); }else if (pid = = 0{printf ("Im child pid=%d, parent id=%d, begin to sleep 5 sec\n"), Getpid (), Getppid ()); Sleep (5); printf ("Im child pid=%d, parent id=%d, End Sleep\n", Getpid (), Getppid ()); Exit (0); }else{//sleep (); printf ("Im Father pid=%d\n", Getpid ()),} printf ("pid =%d, Glob =%d, var =%d\n", Getpid (), Glob, Var);} void func_wait (int sin) {if (sin = = SIGCHLD) {pid_t pid; int stat; if (pid = Wait (&stat)) > 0) {prin TF ("Child%d killed, state is:%d\n", PID, stat);}} return;} void func_waitpid (int sin) {if (sin = = SIGCHLD) {pid_t pid; int stat; if (pid = Waitpid ( -1, &stat, Wnoha NG)) > 0) {//The first parameter is-1, which indicates that all child processes listening to the main process printf ("killed, State is:%d\n", PID, stat);}} return; int main (int argc, char* argv[]) {signal (SIGCHLD, &func_waitpid);//Register the signal function inside the main process, and the child process exits and sends a signal to the parent process. This captures and passes in the signal to the registered function printf ("Im from main before fork\n"); Forktest (); for(;;) {} printf ("Im from main end fork\n");}
Method 2: (Apue on 8.6) Fork two times, with the grandson process to deal with the transaction, the child process to create a grandson process after the exit, the grandson process will become an orphan process, the parent process is the Init process, the grandson process exit will be init after the recovery, the child process will be deleted by the parent process waitpid, but there are The question is that if the parent process executes waitpid first, the child process then creates the grandchild process and exits into a zombie process, then the parent process is not captured. You can sleep in the parent process (1), let the child process first execute the creation of the grandchild process and exit, the parent process to use waitpid recycling (after all, Waitpid will not block).
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>intMain () {pid_t pid; Create first child process PID =Fork (); if (PID < 0{perror ("Fork Error:")); Exit (1 );}//First child process else if (PID = = 0 ) {//child process Create grandchild process printf ("I am the process.pid:%d\tppid:%d\n" ,getpid (), Getppid ()); PID = fork (), if (PID < 0 ) {perror ("Fork Error:" ); Exit (1 );}//The first child process exits because the following else if is only the child process and grandson process execution, and the child process at this time the PID is returned by the fork is >0 (that is, the sun process PID), and the sun process at this time the PID is 0, so else If there is only a child process execution, there is a sentence exit (0) so that the child process is a zombie process, so from sleep (3) only the grandchild process will execute else if (PID >0 ) {printf ("First Procee is exited.\n "); Exit (0 );}//grandson process//sleep 3s ensure that the first child process exits (if the parent process is not waitpid to the child process at this time, the child process is still dead), so that the grandchild process exit (0) will become an orphan process. Reclaimed by the Init process. Sleep (3 ); printf ("I am the second child process.pid:%d\tppid:%d\n" , Getpid (), Getppid ()); exit (0 );}// The parent process exits the first child process, and the following code is only executed by the parent process, and the incoming PID is the child process PID, if (Waitpid (PID, NULL, 0)! = pid) {perror ("Waitepid error:" ) ; Exit (1 ), exit (0 ), return 0 ;
Method 3:
If a zombie process is present and the parent process dies, the zombie process becomes an orphan process, which is reclaimed by the Init process.
Other:
There is a way for a child process or parent process to execute first.
The functions designed are:
Tell_wait ();
Wait_parent ();
Tell_child (PID);
Tell_parent (Getppid ());
Wait_child ();
The principle of implementation is also through the signal
// This code causes the parent process to execute first, after the child process executes the if (pid = fork ()) < 0 ) {printf ( fork error " ); else if (pid = = 0 ) {wait_parent (); // else { do STH about parent .... Tell_child (PID);}
// This code will let the child process execute first, after the parent process executes if 0 { printf ("fork Error"); } Else if 0 ) { //do sth on child .... tell_parent (Getppid ()); } Else { wait_chilid (); // Do sth about parent...}
Refer to the difference between zombie process and orphan process: http://www.cnblogs.com/anker/p/3271773.html
Fork (), zombie process, and orphan process