1.wait函数回收子进程
\qquad父进程可以调用wait()函数回收子进程的终止信息。wait函数有三个功能:
\qquad阻塞等待子进程退出
\qquad回收子进程残留资源
\qquad获取子进程结束状态(退出原因)
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>int main()
{pid_t pid,wpid;pid = fork();if(pid==0){printf("i am child,my id is %d,my parent id is %d\n",getpid(),getppid());sleep(5);printf("--------child die---------\n");}else if(pid>0){ wpid = wait(NULL);if(wpid==-1){perror("wait error");exit(1);}printf("i am parent,my id is %d,my son id is %d\n",getpid(),pid);}else{perror("fork error");exit(1);}return 0;
}
\qquad使用wait(&status)
获取子进程结束的状态,然后把status
传给宏函数来进一步判断进程终止的原因。
\qquadWIFEXITED(status)
为非0,即为真,则进程正常结束,然后使用WEXITSTATUS(status)
,获取进程的退出状态,即exit函数的参数。
\qquadWIFSIGNALED(status)
为非0,即为真,则进程异常终止,然后使用WTERMSIG(status)
,获取终止进程的那个信号的编号。
\qquad子进程的异常终止:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>int main()
{pid_t pid,wpid;int status;pid = fork();if(pid==0){printf("i am child,my id is %d,my parent id is %d\n",getpid(),getppid());sleep(5);printf("--------child die---------\n");//exit(23);execl("/home/linux/2_孤儿进程/error"," ",NULL);}else if(pid>0){ wpid = wait(&status);if(wpid==-1){perror("wait error");exit(1);}else{if(WIFEXITED(status)){printf("子进程已经被回收,且正常结束,退出状态为%d\n",WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf("子进程已经被回收,异常结束,终止子进程的信号为%d\n",WTERMSIG(status));}}printf("i am parent,my id is %d,my son id is %d\n",getpid(),pid);}else{perror("fork error");exit(1);}return 0;
}
\qquaderror
的错误代码:
#include<stdio.h>
int main()
{int a =5;int b;b = a/0;printf("%d\n",b);return 0;
}
\qquad运行结果:
i am child,my id is 7244,my parent id is 7243
--------child die---------
子进程已经被回收,异常结束,终止子进程的信号为8
i am parent,my id is 7243,my son id is 7244
\qquad子进程的正常结束:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>int main()
{pid_t pid,wpid;int status;pid = fork();if(pid==0){printf("i am child,my id is %d,my parent id is %d\n",getpid(),getppid());sleep(5);printf("--------child die---------\n");exit(23);//execl("/home/linux/2_孤儿进程/error"," ",NULL);}else if(pid>0){ wpid = wait(&status);if(wpid==-1){perror("wait error");exit(1);}else{if(WIFEXITED(status)){printf("子进程已经被回收,且正常结束,退出状态为%d\n",WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf("子进程已经被回收,异常结束,终止子进程的信号为%d\n",WTERMSIG(status));}}printf("i am parent,my id is %d,my son id is %d\n",getpid(),pid);}else{perror("fork error");exit(1);}return 0;
}
\qquad程序运行结果:
i am child,my id is 8000,my parent id is 7999
--------child die---------
子进程已经被回收,且正常结束,退出状态为23
i am parent,my id is 7999,my son id is 8000
2.waitpid函数回收子进程
\qquadwaitpid函数有三个参数,第一个可以指定回收子进程的id,回收指定的子进程;第二个和wait函数一样,传入参数int &status
,可以传出进程下一步的判断;第三个参数是int options
,可以修改阻塞状态。
pid_t waitpid(pid_t pid,int &status,int options);
\qquad第一个参数pid
:>0:指定子进程;-1:任意回收一个子进程;0:回收所有子进程;<-1:回收指定进程组内的任意子进程。
\qquad第三个参数options
:当参数为WNOHANG
时,为非阻塞状态;为0时,阻塞等待状态。