在一些项目中需要父进程等待子进程的退出,并且收集子进程的退出状态
如果子进程exit退出后没有收集状态就会变成僵尸进程
调用wait函数
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
status是一个整数型指针
非空的时候:子进程退出状态存放在他所指向的地址中
空:不关心退出状态
如果要检查退出状态需要用到检查wait函数退出状态的宏
宏 | 说明 |
---|---|
WIFEXITED(status) | 当子进程正常结束时返回为真 |
WEXITSTUTAS(status) | 当WIFEXITED(status)为真时调用,返回状态码的低8位 |
WIFSIGNALED(status) | 当子进程异常结束时返回为真 |
WTERMSIG(status) | 当WIFSOGNALED(status)为真时调用,返回引起终止的信号代码 |
示例,子进程在5次后退出,父进程wait,并用WEXITSTATUS(status)打印出exit的退出码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
int main(){
pid_t pid;
int cnt = 0;
int status =10;
pid=fork();
if(pid>0){
wait(&status);
printf("child qiut,child status= %d\n",WEXITSTATUS(status));
while(1){
printf("cnt=%d/n",cnt);
printf("this is father print,pid=%d\n",getpid());
sleep(1);
}
}
else if(pid == 0){
while(1){
printf("this is child print, pid= %d\n",getpid());
sleep(1);
cnt++;
if(cnt ==5){
exit(3);
}
}
}
return 0;
}
如果其所有的子进程都在运行,则父进程阻塞
如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
如果没有任何子进程则返回出错。
而wait使其阻塞,waitpid有一个选项可以使其不阻塞。
waitpid
pid_t waitpid(pid_t pid, int *status, int options);
参数值 | 说明 |
---|---|
pid<-1 | 等待进程组号为pid绝对值的任何子进程。 |
pid=-1 | 等待任何子进程,此时的waitpid()函数等效成了普通的wait()函数。 |
pid=0 | 等待进程组号与目前进程相同的任何子进程,也就是说任何和调用waitpid()函数的进程在同一个进程组的进程。 |
pid>0 (常用) | 等待进程号为pid的子进程。 |
WNOHANG | 如果pid指定的子进程没有结束,则waitpid()函数立即返回0,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号 |
---|---|
WUNTRACED | 如果子进程进入暂停状态,则马上返回。 |
孤儿进程
父进程不等待子进程退出,在退出前就结束自己的生命
Linux的init进程会收留孤儿进程成为他们的父进程