waitpid函数的作用和wait函数的作用相同,只是有些参数不同。
在Linux终端下输入命令:man 2 waitpid
查看waitpid函数的具体描述:
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *wstatus, int options);
作用:回收指定进程号的子进程,可以设置非阻塞(默认阻塞)。
参数:
pid_t pid:
< -1:回收某个进程组的组id的绝对值,回收指定进程组的子进程
-1:回收所有子进程,相当于wait() //最常用
0:回收当前进程组的所有子进程
> 0:某个子进程的id
The value of pid can be:
< -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid.
-1 meaning wait for any child process.
0 meaning wait for any child process whose process group ID is equal to that of the calling process.
> 0 meaning wait for the child whose process ID is equal to the value of pid.
int *wstatus:进程退出时的状态信息,传入的是一个int类型的地址,传出参数。
返回值:
- 成功:返回被回收的子进程的id
- 失败:返回-1(调用函数失败,或者所有子进程都被回收)
int options:设置阻塞或非阻塞
0:阻塞
WNOHANG:非阻塞
返回值:
> 0:返回子进程的id
= 0:options=WNOHANG,表示还有子进程没有退出(在非阻塞的情况下)
-1 :错误,或者没有子进程
WIFEXITED(wstatus)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from
main().
WEXITSTATUS(wstatus)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument
that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main().
This macro should be employed only if WIFEXITED returned true.
WIFSIGNALED(wstatus)
returns true if the child process was terminated by a signal.
下面是waitpid函数的简单案例:
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using std::cout;
using std::endl;
namespace waitpid_test{
void test(){
//有一个父进程创建5个子进程
pid_t pid;
//创建5个子进程
for(int i=0;i<5;++i){
pid = fork();
if(pid == 0)
break;
}
if(pid>0){
//父进程
while(1){
cout<<"parent,pid:"<<getpid()<<endl;
sleep(1);
//int ret = wait(NULL);
int st;
//阻塞
//int ret = waitpid(-1,&st,0);
//非阻塞
int ret = waitpid(-1,&st,WNOHANG);
if(ret == -1)
break;
else if(ret == 0)
//说明还有子进程存在
continue;
else if(ret > 0){
if(WIFEXITED(st))
//是不是正常退出
cout<<"退出的状态码:"<<WEXITSTATUS(st)<<endl;
if(WIFSIGNALED(st))
//是不是异常终止
cout<<"被哪个信号干掉了:"<<WTERMSIG(st)<<endl;
cout<<"child has died,pid:"<<ret<<endl;
}
}
}
else if(pid == 0){
//子进程
while(1){
cout<<"child, pid:"<<getpid()<<endl;
sleep(1);
}
exit(0);
}
}
}
int main(){
//wait_test::test();
waitpid_test::test();
return 0;
}