/*
waitpid 返回值:
> 0 :返回本次 回收掉的子进程ID
== 0 :表示子进程还在运行
== -1 :表示全部子进程已被回收
*/
/*
使用while(1)死循环,持续监测 子进程的回收状态
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
pid = fork();
int status;
if(pid < 0)
{
perror("fork error");
return -1;
}
else if(pid > 0) //父进程
{
printf("parent: pid=[%d]\n",getpid());
pid_t wpid;
while(1)
{
wpid = waitpid(-1,&status,WNOHANG);
if(wpid > 0) // 本次回收掉的进程
{
if(WIFEXITED(status))
{
printf("正常退出,退出码[%d]\n",WEXITSTATUS(status));
}
else if(WIFSIGNALED(status))
{
printf("异常退出,异常信号值[%d]\n",WTERMSIG(status));
}
}
else if(wpid == 0) // 子进程还在运行
{
//printf("子进程还在执行\n");
sleep(20); // ok,明白了非阻塞的用意
// 如果第一次检测子进程时,子进程还在执行,则waitpid(-1,&status,WNOHANG);仍可以返回,
// 转到此条件下执行 父进程的 内容
// 之后再次 waitpid(-1,&status,WNOHANG);检测 子进程的状态,如果 子进程结束,则跳到 wpid == -1 执行退出操作
// 如果在子进程执行期间 父进程的操作更短,又不想,进入多次循环,可以自己设置进入条件
// 总之,是给了我们操作的空间的
}
else if(wpid == -1) // 子进程已经全部回收
{
printf("子进程已经全部回收\n");
break;
}
}
//printf("还会执行吗\n");
//printf("实验证明会执行,但是要等子进程结束之后\n即是阻塞的\n");
}
else //子进程
{
printf("child: pid=[%d]\tppin=[%d]\n",getpid(),getppid());
sleep(2);
return 34;
}
return 0;
}
输出结果: