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
传给宏函数来进一步判断进程终止的原因。
\qquad
WIFEXITED(status)
为非0,即为真,则进程正常结束,然后使用WEXITSTATUS(status)
,获取进程的退出状态,即exit函数的参数。
\qquad
WIFSIGNALED(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;
}
\qquad
error
的错误代码:
#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函数回收子进程
\qquad
waitpid函数有三个参数,第一个可以指定回收子进程的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时,阻塞等待状态。