1)进程等待相关概念
- 什么是?父进程通过等待的方式,回收子进程资源,获取子进程的退出信息;
- 为什么?防止子进程发生僵尸问题,回收子进程资源,避免内存泄漏;获取子进程退出时的退出信息;
- 怎么做?通过使用wait( )、waitpid( )函数进行系统调用。
2)pid_t wait(int* status)
- wait成功返回所等待子进程的pid,失败返回-1,表示子进程还没有退出;等待方式默认为阻塞式等待。
3)pid_t waitpid(pid_t pid, int* status, int option)
- pid可取值为任意子进程的pid,当其取值为-1时,表示等待任意一个子进程;
- 关于status:
- status是一个输出型参数,子进程退出后,操作系统会从PCB中读取子进程的退出信息,保存在status所指向的变量中;
- 当其值为NULL时,表示等待的时候并不关心子进程的退出状态;
- status可以看做是一个位图,我们一般只看它的低16位,其中次低8位表示进程退出时的退出状态(正常退出),低7位表示 终止信号(被信号杀死);
- 相关图示如下:
![status](https://img-blog.csdnimg.cn/98a1683d8f484867913adc9cd92c2d9c.png#pic_center)
- option取值为0时,表示以阻塞的方式进行等待;取值为WNOHANG时,表示以非阻塞的方式进行等待,当其以非阻塞方式等待时,函数返回值为0表示子进程还没有退出,返回值大于0表示子进程退出了;
- (status&0x7f)0:表示正常退出,(status>>8)&0xff0:表示异常退出;
- 当然,操作系统中也有相应的宏让我们去使用:
WIFEXITED(status)---- 判断子进程是否正常退出,若进程是正常终止,则返回真;
WEXITSTATUS(status)---- 获取子进程的退出码。
4)测试代码----以阻塞方式进行等待
int main(){
printf("begin start...\n");
pid_t id = fork();
if(id == 0){
int count = 0;
while(count<5){
printf("child %d is running...\n", getpid());
sleep(1);
count++;
}
exit(10);
}
else if(id > 0){
int status = 0;
pid_t ret = waitpid(id, &status, 0);
if(WIFEXITED(status)){
printf("ret: %d\n", ret);
printf("child exit code: %d\n", WEXITSTATUS(status));
printf("child exit code: %d\n", (status>>8)&0xff);
printf("father wait end...\n");
}
else if(ret>0){
printf("status: %d\n", status);
printf("child exit code: %d\n", (status)&0x7f);
printf("father wait end...\n");
}
else{
printf("wait failed...\n");
}
}
else{
printf("error......");
}
}
5)测试代码----以非阻塞方式进行等待
int main(){
printf("begin start...\n");
pid_t id = fork();
if(id == 0){
int count = 0;
while(count<5){
printf("child %d is run\n", getpid());
sleep(1);
count++;
}
exit(10);
}
else if(id > 0){
int status = 0;
pid_t ret = 0;
do{
ret = waitpid(id, &status, WNOHANG);
if(ret==0){
printf("child is running...\n");
}
sleep(2);
}while(ret==0);
if(WIFEXITED(status)){
printf("status: %d\n", status);
printf("child exit code: %d\n", WEXITSTATUS(status));
printf("father wait end...\n");
}
else{
printf("wait failed...\n");
}
}
else{
printf("error......");
}
}