1.回收子进程
孤儿进程:父进程先于子进程结束,无法回收子进程,此时init进程孤儿院领养子进程成为其新父进程
僵尸进程:父进程在循环中,无法回收子进程,子进程终止一直等父进程回收,此时子进程残留资源PCB,存放在内核中成为僵死状态。
(用wait系列函数回收子进程)
2.wait函数( pid_t wait(int *status) , 成功,子进程pid,失败,-1(没有子进程))
父进程调用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方法回收子进程
#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的使用
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 }