After creating the process, in order to avoid the zombie process, the waste of resources and the number of processes idle Occupy, you need to recycle the process resources, here the main look at wait and waitpid two processes function and difference!!
One, pid_t wait (int *status)
role (1): Cleanup The end of the child process resources or get the process after the execution of the return information;
Once the process has called wait, it blocks itself immediately, and the wait automatically parses if a child process of the current process has exited (primarily a recycling resource), and if it finds such a child process that has become a zombie, wait collects the child process information and destroys it and returns If no such sub-process is found, wait is stuck here until one appears.
parameter status:Used to save some state when the collection process exits, because we need to determine if our process is performing successfully. It is a pointer to type int. But if we don't care about how this subprocess dies, we just want to get rid of this zombie process (and in most cases we will), we can set this parameter to NULL, just like this:
PID = Wait (NULL);
If it is not the null,wait that will be stored in some state when the process exits, this is an integer value (int) indicating the state at which the child process exited.
The two most commonly used:
wifexited (status):True if it is normal to terminate. At this point the executable wexitstatus (status): Takes a child process to the lower 8 bits of the exit or _exit parameter. When wifexited returns a value other than 0, we can use this macro to extract the return value of the child process, if the child process calls exit (5), Wexitstatus (status) returns 5, or Wexitstatus (status) returns 7 if the child process calls exit (7). Note that if the process does not exit normally, that is, wifexited returns 0, this value is meaningless.
wifsignaled (status):True if the exception is terminated. The executable Wtermsig (status) At this time: take the signal number that terminates the child process;
wifstopped (status): True if the child process is currently paused. Executable Wstopsig (status) At this time: take the signal number that causes the child process to pause;
return value:
success:Wait returns the process ID of the child process being collected;
failure : If the calling process does not have child processes, the call fails, and wait returns-1. At the same time errno is placed in Echild.
program Example 1:
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h>main () { pid_t pc,pr; Pc=fork (); if (pc<0)//Determine if the process was created successfully; printf ("Error ocurred!/n"); else if (pc==0)//If it is a subprocess { printf ("This is a child process with PID of%d\n", Getpid ()); Sleep (5); Let the child process wait for 5S; } Else {//If it is the parent process pr=wait (NULL);//The parent process will wait here for 5S, waiting for the end of the child process; printf ("I catched A Child process with PID of%d\n ", PR); } Exit (0);//exit normally;}
Operation Result:
Can obviously feel the printing of the second sentence, the program waited for 5 s, as long as the call to wait (), the parent process will wait until the end of the child process, to capture the status of the child process, in order to exit gracefully. In fact, no matter how much time we set, the parent process will wait forever.
program Example 2:
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h>main () { int status; pid_t PC,PR; Pc=fork (); if (pc<0)//create process error; printf ("Error ocurred!\n"); else if (pc==0) {//Sub-process printf ("This is a child processes with PID of%d.\n", Getpid ()); Exit (10); The child process returns 10 after a successful call, using this return value to see if the child process is running smoothly; } Else {//Parent process pr=wait (&status); If wifexited (status) {///if wifexited returns a value other than 0, the execution of the child process succeeds; printf ("The Children process%d exit normally.\n", PR); printf ("The Return code is%d.\n", Wexitstatus (status)); Again to determine whether the code and location we want to execute is executed, }else//If wifexited returns zero, the child process is not executed successfully; printf ("The Children procedure%d exit abnormally . \ n ", PR);} }
Operation Result:
Through this program we can use the return value of the child process to determine whether the child process is executed smoothly and return;
program Example 3:
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h>main () {PID _t pc, Pr;pc=fork (); if (pc<0)//If fork error printf ("Error occured on forking.\n"); else if (pc==0) {//Child process sleep (5);//sleep 5 seconds E XIT (0);} Parent process Do{pr=waitpid (PC, NULL, Wnohang);//using the Wnohang parameter, Waitpid will not wait here, nonblocking wait (), if (pr==0) {//If no child process is collected, Collected to return pidprintf ("No child exited\n"); sleep (1);}} while (pr==0);//No child process is collected, go back to try again, if (PR==PC)//Find a subprocess and recycle; printf ("Successfully get child%d\n", PR); elseprintf ("some Error occured\n ");}
Operation Result:
As can be seen from the results, if the Wnohang parameter is added, the parent process waits for the end of the child process, but does not wait until it is interrupted, which improves the running efficiency of the program. Not death!!
Role (2): Process synchronization problem;
When the fork call succeeds, the parent-child process does everything, but when the parent process ends and needs to use the result of the child process, it stops calling wait, waits until the child process is finished, and then proceeds with the child process, which successfully solves the process synchronization problem we put forward.
Program Examples:
#include <sys/types.h> #include <sys/wait.h> #include <stdio.h>main () {pid_t pc, Pr;int status,a,b,c, Sum;a=10;b=2;pc=fork (); if (pc<0) printf ("Error occured on forking.\n"), else if (pc==0) {///Sub-process work, value of C; printf ("This is child process,id:%d,pid:%d. ", Getpid (), Getppid ()); C=a+b;exit (c);} else{//the work of the parent process pr=wait (&status);//Use the result of the child process c;if (status)//If wifexited returns a value other than 0, the child process executes successfully; {printf ("This I s father process,id:%d.\n ", Getpid ()); Sum=wexitstatus (status);//Get the result of child process; printf ("%d\n ", sum);//output sub-process results;}else{ printf ("The child process%d exit abnormally.\n", PR);}}
Operation Result:
This program can show that the work of the parent process depends on the execution result of the child process, so it must wait for the end of the child process;
Second, pid_t waitpid (pid_t pid,int *status,int options);
Wait&waitpid differences:
WAITPID provides 3 features that the wait function cannot achieve:
(1), Waitpid waits for a specific child process, and wait returns a subprocess of either terminating state;
(2), Waitpid provides a wait for a non-blocking version;
(3), WAITPID support job control (with wuntraced option). A macro that checks for wait and waitpid two functions that return the terminating state: The child process states returned by these functions are saved in the status pointer, and the following 3 macros can be used to check the status:
wifexited (status): True if it is normal to terminate. At this point the executable wexitstatus (status): Takes a child process to the lower 8 bits of the exit or _exit parameter.
Wifsignaled (status): True if the exception is terminated. The executable Wtermsig (status): Takes the signal number that causes the child process to terminate.
wifstopped (status): True if the child process is currently paused. Executable Wstopsig (status): Takes a signal number that causes the child process to pause
Essentially, system calls Waitpid and wait are the same, but Waitpid has two more user-controlled parameterspid and Options,This gives us another, more flexible way to program. Let's take a look at these two parameters in more detail:
First parameter:PID: From the parameter's name PID and type pid_t, it can be seen that a process ID is required here. But when the PID takes a different value, there are different meanings here.
Pid>0, only wait for the process ID equal to the PID of the child process, no matter how many other child processes have been run to end the exit, as long as the specified child process has not ended, Waitpid will continue to wait.
Pid=-1, wait for any child process to exit without any restrictions, at which time waitpid and wait do exactly the same.
Pid=0, wait for any child process in the same process group, and Waitpid will not ignore it if the child process has joined another process group.
Pid<-1 waits for any child process in a specified process group, the ID of the process group equals the absolute value of the PID.
a second parameter: status, save some state when the collection process exits; normal exit or abnormal exit;
A third parameter:Options provide some additional options to control Waitpid, currently Linux supports both Wnohang and wuntranced options, which are two constants;
Wnhang: Even if no child process exits, he will return immediately, and will not wait as long as wait, that is, a non-blocking wait;
For example:
Ret=waitpid ( -1,null,wnohang);//non-blocking wait (); Pr=waitpid (PC, NULL, 0); pr=wait (null) is exactly the same;
wuntraced: It involves some tracking debugging information;
In fact, wait is a packaged waitpid:
Static inline pid_t Wait (int * wait_stat) { return waitpid ( -1,wait_stat,0); }
return values and Errors
The return value of the waitpid is slightly more complex than wait, with a total of 3 cases:
1, when the normal return, Waitpid returned to the collected sub-Process ID of the process;
2, if the option is setWnohang,The call in Waitpid finds that no child process that has exited can be collected, then returns 0;
3, if there is an error in the call, then return-1, then errno will be set to the corresponding value to indicate the error, when the PID indicates that the child process does not exist, or the process exists, but not the child process of the call process, Waitpid will be returned with an error, then errno is set to Echild;
issue: How to make the parent process call Wait () and waitpid () to avoid the embarrassment of hanging, also can smooth reclaim the resources of the child process, avoid the zombie process:
(1).you can use the signal function to install handler for SIGCHLD. After the child process finishes, the parent process receives the signal and can call the wait recycle in handler.
(2). If the parent process does not care about when the child process ends, it can be usedsignal (SIGCLD, sig_ign) or signal (SIGCHLD, sig_ign) notifies the kernel that it is not interested in the end of the child process, then after the child process is finished,the kernel recycles and no longer sends a signal to the parent process。
(3).Fork two times,The parent process fork a child process, and then continues to work, the child process fork a grandchild process after exiting,then the grandchild process is taken over by Init, and after the grandchild process is finished, Init is recycled. But the recycling of the child process to do their own (immediately recycle, is the Sun process programming orphan process).
Blog post reference:
http://blog.csdn.net/kevinhg/article/details/7001719
Http://blog.sina.com.cn/s/blog_590be5290100nc51.html
Http://blog.chinaunix.net/uid-25365622-id-3045460.html
Thank bloggers for sharing!
Wiat () and Waitpid ()