Linux environment programming-waitpid (zombie process recycling)

The previous article introduced the recovery of the zombie process of wait. Now let’s introduce waitpid (similar to wait), then how to use this function?

Let’s talk about it first. You don’t need to remember these things. Just leave an impression and check. 

The role of waitpid is the same as wait, without blocking. And you can specify the process ID to clean up the process. Its return value is somewhat special

pid_t  waitpid(pid_t pid,  int *status, int options);   

  • Success: return the ID of the child process cleaned up
  • Failure: return -1 (no child process)
  • There is another return 0; the child process has not ended yet (cannot be recycled) 

Take a look at the parameters:

pid:   

  •          > 0 means recycling the specified child process
  •          -1 Recycle any child process (equivalent to wait)
  •          0 Recycle all child processes that are currently and in a group that calls waitpid
  •         <-1 Recycle any child process in the specified process group

Note: One call to waitpid or wait can only recycle one child process. To recycle more than one child process, you should use a loop

options:

The parameter option can be 0 or the following OR combination:
1. WNOHANG If there is no child process that has ended, it will return immediately and not be given
wait.
2. WUNTRACED if the child process enters the suspended execution situation, it returns immediately, but ends
The status is ignored.
The end status of the child process is stored in the status after the return , there are several macros below to determine the end situation
condition:
3. WIFEXITED ( status ) is a non- zero value if the child process ends normally .
4. WEXITSTATUS ( status ) gets the end code returned by the child process exit (), one
Generally, WIFEXITED will be used to judge whether it ends normally before using this macro.
5. WIFSIGNALED ( status ) If the child process ends because of a signal, this macro value is
true
6. WTERMSIG ( status ) to obtain the signal code of the child process aborted by the signal, generally
Will use WIFSIGNALED to judge before using this macro.
7. WIFSTOPPED ( status ) If the child process is in a suspended execution situation, this macro value is
true. This is generally only the case when WUNTRACED is used.
8. WSTOPSIG ( status ) to obtain the signal code that caused the child process to suspend, usually first
Use WIFSTOPPED to judge before using this macro.
 

Code Demo

#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>


using namespace std;

#define FORK_NUM 5

int
main(int argc, char* argv[])
{
        pid_t pid, rmpid;
        int i;

        for(i=0; i<FORK_NUM; i++){
                pid = fork();
                if(pid == 0){
                        break;
                }else if(pid > 0){
                        printf("creat %dth son \n", i+1);
                        if(i == 2){
                                rmpid = pid;
                        }
                }else{
                        printf("creat %dth son error\n", i+1);
                }
        }

        sleep(i+1);

        if(i==FORK_NUM){
                int status;
                printf("I am parent\n");
        #if 0   // wait one son progress
                if(waitpid(rmpid, &status, 0) == -1){// only wait 3th son progress
                        perror("waipid error");
                        exit(1);
                }
                if(WIFEXITED(status)!=0 && WIFSIGNALED(status)==0){ 
                        printf("son progress normal exit\n");
                        printf("son progress exit status : %d \n", WEXITSTATUS(status));
                }else{// 0   
   printf("son expretion exit,signal ID:%d \n",  WTERMSIG(status));
                }
                printf("the %dth is waitpided by me\n", i+1);
                while(1)sleep(1); 
        #else  // wait all of son progress
                do{
                        rmpid = waitpid(-1, &status, WNOHANG);
                        if(rmpid == 0){
                                sleep(1);
                                continue;
                        }
                        else if(rmpid == -1)break;
                        else{
                                i--;
                                printf("has %d son progress wll to be wait\n", i);
                        }

                }while(i > 0);

                while(1) sleep(1);

        #endif
        }else{
                printf("I am child %d \n", i+1);
        }


        return 0;
}

     
 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_44065088/article/details/108690543