Recycling child process --wait method and waitpid

1. Recycling child process

孤儿进程:父进程先于子进程结束,无法回收子进程,此时init进程孤儿院领养子进程成为其新父进程

Zombie process: the parent process in a loop, you can not recover the child, the child process to terminate the parent process has been waiting for recovery, then the child remaining resources PCB, stored in the kernel becomes dead state.
(Recovery of the child process with the wait family of functions)

2.wait function (pid_t wait (int * status), the success of the child process pid, failure, -1 (not the child))

      父进程调用wait函数可以回收子进程,该函数有三个功能:
(1)父进程阻塞等待子进程退出
(2)回收子进程残留资源
(3)获取子进程的结束状态(退出原因)
        用status来保存进程的退出状态,借助宏函数进一步判断具体原因,宏函数分为三组:
(1)WIFEXITED(status)----非0---进程正常退出(若正常退出,可以用下一个宏函数获取退出状态)
    WEXITSTATUS(status)---------获取退出状态(exit的参数)
(2)WIFSIGNALED(status)---非0---进程异常终止(若异常终止,可以用下一个宏函数判断是哪个信号使其终止,获取该信号的编号)
    WTERMSIG(status)-------------获取进程终止信号的编号

3.waitpid函数( pid_t waitpid( pid_t pid, int * status, int options) )

wait 只能自己阻塞回收子进程,且不能回收指定子进程
waitpid可以阻塞回收也可以非阻塞回收(options指定为WNOHANG为非阻塞),且可以回收指定子进程

参数1 pid:  pid----回收指定子进程
	-1------回收任意一个子进程
参数2  status: 想知道进程退出状态&status,不想知道就NULL
参数3  option:0-----------------阻塞回收,和wait一样
	       WNOHANG------非阻塞回收。
返回值:pid------------已经回收的子进程pid
	0------------所有子进程都在执行中,无法回收	

(1)想阻塞回收所有子进程:while( wait(NULL)){};    /      while(  waitpid( -1,NULL, 0 )   )    
(2)想非阻塞回收所有子进程:do{ 
			wpid = waitpid(-1,NULL,WNOHANG);
			if(wpid >0){n--;}  //n为子进程数量,非阻塞,即为轮询方式回收
			}while(n>0)

wait recovered child process

 #include<stdio.h>
  2 #include <stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/wait.h>
  5 #include<sys/types.h>
  6 int main()
  7 {
  8         pid_t pid, pwait;
  9         pid =  fork();
 10         int status;
 11         if(pid == -1)
 12         {
 13                 perror("fork error");
 14                 exit(1);
 15         }
 16         else if(pid == 0 )
 17         {
 18                 printf("-----i am child pid = %d, my parent=%d\n",getpid(),getppid());
 19                 sleep(100);
 20                 printf("-------child die---------\n");
 21                 exit(1);
 22         }
 23         else
 24         {
 25                 pwait = wait(&status);
 26                 if(pwait == -1)
 27                 {
 28                         perror("wait error");
 29                         exit(1);
 30                 }
 31                 if(WIFEXITED(status))//wait正常退出
 32                 {
 33                         printf("child exit with %d\n",WEXITSTATUS(status));
 34                 }
 35                 if(WIFSIGNALED(status))//wait异常退出
 36                 {
 37                         printf("child exit with %d\n",WTERMSIG(status));
 38                 }
 39                 printf("-------partent die------\n ");
 40 
 41         }
 42         return 0;
 43 }

waitpid use

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 int main()
  5 {
  6         pid_t pid ,pid1;
  7         pid_t wpid;
  8         printf("xxxxxxxxxxxxxxxxxxxxxxxxxx\n");
  9 
 10 
 11         int i=0;
 12         for(i=0;i < 5; i++)
 13         {
 14 
 15              pid = fork();
 16              if(pid == -1)
 17              {
 18                 perror("fork error");
 19                 exit(1);
 20              }
 21              else if(pid == 0)
 22              {
 23                      break;
 24              }
 25              if(i ==3)
 26              {
 27                     pid1 = pid;
 28              }
 29         }
 30 
 31         if(i < 5)
 32         {
 33                 sleep(i);
 34                 printf("i am %dth child:pid = %d,ppid =%d\n",i+1,getpid(),getppid());
 35                 exit(1);
 36         }
 37         else
 38         {
 39                 sleep(i);
 40                 printf("i am parent, pid = %d\n",getpid());
 41                 do
 42                 {
 43                         wpid = waitpid(-1,NULL,WNOHANG);
 44                         if(wpid > 0)
 45                                 i--;
 46                 }while(i>0);
 47                 printf("parent finish\n");
 48                 //while(wait(-1,NULL,0)){};     
 49                 //waitpid(pid1 , NULL,0);   //0为阻塞状态回收
 50                 //wait(NULL);
 51                 //while(wait(NULL)){};
 52                 //while(1);
 53         }
 54 
 55 
 56         return 0;
 57 }

Published 38 original articles · won praise 13 · views 4337

Guess you like

Origin blog.csdn.net/YanWenCheng_/article/details/103929990