目录
一、进程等待的原因
二、进程等待的方法
(一)wait方法
1. 定义
2. 进程等待能回收子进程的僵尸状态(wait方法验证)
3. 子进程没退出时,父进程在wait上进行阻塞等待,直到子进程僵尸,wait自动回收(wait)
(二)waitpid方法
(三)获取子进程status
1. status结构
2. 我们不能对status整体使用
3. 正确使用
(四)图示说明父进程等待子进程的方式
#include
#include
pid_t wait(int*status);
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
#include
#include//exit的头文件
#include//fork头文件
#include//pid_t类型的头文件
#include//wait头文件
void Worker()
{
int cnt = 3;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)//子进程
{
Worker();
exit(0);
}
else
{//父进程
sleep(5);
pid_t rid = wait(NULL);
if(rid == id)
{
printf("wait a process,pid: %d\n",getpid());
}
sleep(5);
}
return 0;
}
#include
#include//exit的头文件
#include//fork头文件
#include//pid_t类型的头文件
#include//wait头文件
void Worker()
{
int cnt = 3;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)//子进程
{
Worker();
exit(0);
}
else
{//父进程
printf("wait before!\n");//回收之前
pid_t rid = wait(NULL);
printf("wait after!\n");//回收之后
if(rid == id)
{
printf("wait a process,pid: %d\n",getpid());
}
sleep(5);
}
return 0;
}
pid_ t waitpid(pid_t pid, int *status, int options);
pid
参数指定了要等待的子进程的进程ID。它可以取以下几个值:
-1
:等待任意一个子进程,类似于 wait
函数。0
:等待指定进程ID的子进程。status
是一个指向整型的指针,用于接收子进程的退出状态信息。如果子进程正常结束,会将退出状态信息存放在这个指针指向的位置。status
的内容会被填充为一个整数,其中包含了子进程的退出状态信息。可以通过宏来解析这个整数,比如:
WIFEXITED(status)
:若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status)
:若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)options
是一个整型参数,可以用来指定一些选项,比如 WNOHANG
可以使 waitpid
变为非阻塞调用。#include
#include//exit的头文件
#include//fork头文件
#include//pid_t类型的头文件
#include//wait头文件
void Worker()
{
int cnt = 3;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)//子进程
{
Worker();
exit(10);
}
else
{//父进程
printf("wait before!\n");//回收之前
int status;
pid_t rid = waitpid(id, &status,0);
printf("wait after!\n");//回收之后
if(rid == id)
{
printf("wait a process,pid: %d, status: %d\n",getpid(),status);
}
sleep(5);
}
return 0;
}
#include
#include//exit的头文件
#include//fork头文件
#include//pid_t类型的头文件
#include//wait头文件
void Worker()
{
int cnt = 3;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)//子进程
{
Worker();
exit(10);
}
else
{//父进程
printf("wait before!\n");//回收之前
int status;
pid_t rid = waitpid(id, &status,0);
printf("wait after!\n");//回收之后
if(rid == id)
{//我们不能对status整体使用
printf("wait a process,pid: %d, rpid: %d, exit sig: %d, exit code: %d\n",getpid(),rid, status&0x7F, (status>>8)&0xFF);
}
sleep(5);
}
return 0;
}