文章目录
进程等待
父进程等待子进程推出,获取其退出返回值,释放子进程的资源
目的:避免产生僵尸进程
头文件:#include <sys/wait.h>
1、 pid_t wait(int *status);
阻塞等待任意一个子进程退出,通过status获取退出返回值,释放资源
**返回值:**若成功,返回退出的子进程的pid;若出错,返回-1
2、pid_t waitpid(pid_t pid, int *status, int options);
可以等待任意一个子进程退出,也可以等待指定的子进程退出
pid_t pid:等于-1,表示等待任意子进程退出;大于0,表示等待指定子进程退出
可以是阻塞等待子进程退出,也可以是非阻塞等待子进程退出
int options:设置为0,执行阻塞等待;设置为WNOHANG,则执行非阻塞等待
返回值:若成功,返回子进程pid;
若没有子进程退出,返回0(非阻塞状态下,阻塞状态下会一直等待);
出现错误,返回-1
注意:如果有已经退出的子进程,wait/waitpid会直接处理,无需等待
阻塞和非阻塞
阻塞:为了完成一个功能,发起一个调用,若功能完成条件不具备,就一直等待
非阻塞:为了完成一个功能,发起一个调用,若功能完成条件不具备,立即报错返回
代码示例:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int pid=fork();
if(pid<0)
{
//出错
perror("fork error");
return -1;
}
else if(pid==0)
{
//子进程
sleep(5);//休眠5秒
return 99;//main中的return--退出子进程,退出返回值为99
}
else
{
//父进程
while(1)sleep(1);//保持休眠
}
return 0;
}
子进程休眠5秒后退出,进入僵尸态,会发生内存泄漏
下面修改代码,加入内存等待操作
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
int pid=fork();
if(pid<0)
{
//出错
perror("fork error");
return -1;
}
else if(pid==0)
{
//子进程
sleep(5);
return 99;//main中的return--退出子进程,退出返回值为99
}
//int ret=waitpid(-1,NULL,0); //与21行等价,用哪个都行
int ret=wait(NULL);//等待任意子进程退出
printf("progress:%d exit\n",ret);
//父进程
while(1)sleep(1);//死循环
return 0;
}
打印信息:pid=6035的子进程退出
结果显示子进程直接退出,已经不存在了
再来看waitpid非阻塞状态的代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
int pid=fork();
if(pid<0)
{
//出错
perror("fork error");
return -1;
}
else if(pid==0)
{
//子进程
sleep(5);
return 99;//main中的return--退出子进程,退出返回值为99
}
// int ret=wait(NULL);
// printf("progress:%d exit\n",ret);
int ret;
while((ret=waitpid(-1,NULL,WNOHANG))==0)
{
//非阻塞状态下,没有子进程退出,返回0
printf("当前子进程还没有退出\n");
sleep(1);
}
if(ret<0)
{
perror("waitpid error:");
}
printf("progress:%d exit\n",ret);
//父进程
while(1)
{
sleep(1);//死循环
}
return 0;
}