Simple introduction-Wait () and waitpid () functions of UNIX multi-process Programming

Source: Internet
Author: User

Wait and waipid Functions

 

When a process terminates normally or abnormally, the kernel sends a sigchld signal like its parent process, because the child process is a one-step event, therefore, this signal is also an asynchronous notification sent by the parent process of the kernel. The parent process can ignore the signal or provide a function that is called when the signal occurs. The default action for this signal is to ignore it.

Now you need to know what may happen to the process that calls wait or waitpid:

 

  • If all its sub-processes are running, it will be blocked.
  • If a child process has been terminated and the parent process in progress has been terminated, the child process's termination status will be immediately returned.
  • If no sub-process exists, an error is returned immediately.

 

If the process calls wait because it receives the sigchld signal, it is expected that wait will return immediately. However, if wait is called at any time, the process may be blocked.

 

Two function prototypes

# Include <sys/Wait. h> pid_t wait (int * status); pit_t wait (pid_t PID, int * status, int options); if the function succeeds, the process ID is returned. If an error occurs, the system returns-1;

 

The following is a simple example to show our wait functions.

 

#include "apue.h"#include <sys/wait.h> int main(void){        pid_t pid1,pid2;       printf("before fork\n");               if((pid1=fork())<0){               printf("fork error");        }else if(pid1==0){                printf("child process 'spid=%d\n",getpid());                sleep(3);        }else{               pid2=wait(NULL);               printf("wait process 's pid=%d\n",pid2);        }        exit(0);}

 

Output result:

 

When the program is running, it is obvious that three seconds are waiting for the output of the last line. That is, the parent process waits for the child process to end. Only the parent process can capture the child process and obtain the wait result.

 

Parameter status:

The status parameter is an integer pointer. If the value of the status parameter is not null, wait will take out the status of the sub-process and store it in it. This is an integer (INT ), it indicates whether the sub-process Exits normally or is ended abnormally (a process can also be ended by another process with a signal, which will be introduced in future articles ), and the return value at the normal end, or information about which signal is terminated. Because the information is stored in different binary bits of an integer, It is very troublesome to read it using the conventional method. People have designed a special macro (macro) to complete this work, next, let's take a look at two of the most common ones:

1. The wifexited (Status) macro is used to indicate whether the sub-process Exits normally. If yes, it returns a non-zero value.

(Please note that, although the name is the same, the parameter status here is not the only parameter of wait -- the pointer to the integer status, but the integer pointed to by the pointer. Remember not to confuse it .)

2. wexitstatus (Status) When wifexited returns a non-zero value, we can use this macro to extract the return value of the sub-process. If the sub-process calls exit (5) to exit, wexitstatus (Status) 5 is returned. If the sub-process calls exit (7), wexitstatus (Status) returns 7. Note that if the process does not exit normally, that is, if wifexited returns 0, this value is meaningless.

Detailed tables in the book

 

The following example shows how to obtain the termination signal of a sub-process. Then output.

#include "apue.h"#include<sys/wait.h> void pr_exit(int); int main(void){        pid_t pid;        int status;        if((pid=fork())<0){               err_sys("fork error");        }else if(pid==0){                exit(7);        }        if(wait(&status)!=pid)               err_sys("wait error");        pr_exit(status);        if((pid=fork())<0)               err_sys("fork error");        else if(pid==0)        //      printf("child  pid=%d\n",getpid());                 //printf("child pid=%d\n",getppid());                abort();         if(wait(&status)!=pid)               err_sys("wait error");        pr_exit(status);        if((pid=fork())<0)               err_sys("fork error");        else if(pid==0)               //printf(" parent pid=%d\n",getppid());                 //printf("child  pid=%d\n",getpid());                status/=0;        if(wait(&status)!=pid)               err_sys("wait error");                                                                                                                                              pr_exit(status);                                                                                                                                                                                                                                                                                                                                          exit(0);                                                                                                                                                                                                                                                                                                                                          }                                                                                                                                                                                                                                                                                                                                                         void pr_exit(int status)                                                                                                                                                     {                                                                                                                                                                                    if(WIFEXITED(status))                                                                                                                                                               printf("normal termination,exitstatus=%d\n",WEXITSTATUS(status));                                                                                                   elseif(WIFSIGNALED(status))                                                                                                                                                        printf("abnormal termination,signalstatus=%d\n",WTERMSIG(status),                                                                                           #ifdef WCOREDUMP                                                                                                                                                                                            WCOREDUMP(status)?"(core file generated)":"");                                                                                                                                                                                                                                                                            #else                                                                                                                                                                                       "");                                                                                                                                                         #endif                                                                                                                                                                               elseif(WIFSTOPPED(status))                                                                                                                                                         printf("child stopped ,signal number=%d\n",                                                                                                                                                 WSTOPSIG(status));                                                                                                                                                                                                                                                                                                         }   

 

Output result:

 

From the results, we can see that calling exit is a normal termination function.

 

Waitpid function.

When we need to wait for a function of a specific process, we need to use the waitpid function at this time. From the above we can see the waitpid function prototype, we also know that there is a pid_t parameter.

Explanation:

PID =-1, waiting for any sub-process. It is equivalent to wait.

PID> 0. Wait for the child process whose process ID is equal to the PID.

PID = 0 wait for any sub-process whose group ID is equal to the called process group ID.

PID <-1 waits for any sub-process whose group ID is equal to the absolute value of PID.

 

Waitpid returns the process ID of the final child process. The sub-Process Termination status is stored in the storage unit indicated by status.

 

The waitpid function provides three functions not provided by the wait function.

Waitpid can wait for a specific process, while wait returns the status of any final sub-process.

Waitpid provides the yigewait fee blocking version. Sometimes you want to get the status of a sub-process, but do not want to block it.

Waitpid supports job control.

 

Waitpid return value and error

 

The return value of waitpid is slightly more complex than that of wait. There are three cases:

  1. When the returned result is normal, waitpid returns the ID of the collected sub-process;
  2. If the wnohang option is set, and waitpid in the call finds that no child process has exited to collect data, 0 is returned;
  3. If an error occurs in the call,-1 is returned. errno is set to a value to indicate the error;

When the sub-process indicated by the PID does not exist or the process exists but is not a sub-process that calls the process, waitpid will return an error, and errno is set to echild;

# Include <sys/types. h> # include <sys/Wait. h> # include <unistd. h> int main () {pid_tpc, PR; Pc = fork (); If (Pc <0) {/* If fork Error */printf ("erroccured on forking. \ n ");} elseif (Pc = 0) {/* if it is a sub-process */sleep (10);/* sleep for 10 seconds */exit (0 );} /* if the process is parent */do {Pr = waitpid (PC, null, wnohang);/* If the wnohang parameter is used, waitpid will not wait here */If (Pr = 0) {/* If the sub-process is not collected */printf ("nochild exited \ n "); sleep (1) ;}}while (Pr = 0);/* If the sub-process is not collected, go back and try again */If (Pr = pc) printf ("successfullyget child % d \ n", Pr); else printf ("someerror occured \ n ");}

 

Output result:

 

From the results, we can see that the parent process has been waiting for the completion of the Child process.

 

Wait () and waitpid () are described here. If you have any questions, please contact us.

 

More articles, welcome to pay attention to http://blog.csdn.net/wallwind copyright owned by the blogger ~~ Commercial use prohibited

 

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.