函数简介
函数原型
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
描述
waitpid()
会挂起调用的进程,直到由参数pid
指定的子进程状态改变,一默认情况下,只等待子进程的退出,可以通过options
参数进行修改。
参数
pid
- 进程的pid,pid的取值不同实际意义也会不同:
< -1
等待进程组中的任何子进程退出,进程组的ID为pid的绝对值
-1
等待任何子进程,此时与wait函数的作用相同(常用)
0
等待与调用进程为同一进程组的任何子进程退出
> 0
等待进程ID为pid的子进程退出
status
- 如果不为NULL,则存储状态信息,常用值(详细请参考man waitpid):
WIFEXITED(status)
返回true如果进程正常退出,也就是说调用exit或main函数退出
WEXITSTATUS(status)
获取子进程的退出信息,只有在WIFEXITED返回true时有效
WIFSIGNALED(status)
返回true如果进程被信号终端
WTERMSIG(status)
获取引起子进程退出的信号值,只有在WIFSIGNALED返回true时有效
options
- 可以为0,或以下选项的逻辑组合:
WNOHANG
即使没有子进程退出,也会立即返回
WUNTRACED
子进程被挂起是也会返回
WCONTINUED
子进程被恢复是也会返回
返回值
返回状态改变的子进程的pid,如果设置了WNOHANG
选项则如果当前没有退出的子进程可收集的时候返回0,如果错误则返回-1。
实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define CREATE_PROCESS_CNT 5
int main(void)
{
pid_t pid;
int i;
int status;
for(i = 0; i < CREATE_PROCESS_CNT; i++) {
pid = fork();
switch(pid) {
case -1: /*error*/
perror("fork");
exit(1);
break;
case 0: /*child*/
printf("I am child, exit status:%d pid:%d ppid:%d\n", i, getpid(), getppid());
exit(i);
break;
default: /*parent*/
break;
}
}
sleep(1); //make sure all children had exited, before.
i = 0;
for( ;; ) {
pid = waitpid(-1, &status, WNOHANG);
if(pid == 0) { /* no child*/
printf("no child to be waited\n");
sleep(1);
}
if(pid > 0) {
printf("collected child pid[%d] exit status is %d\n", pid, WEXITSTATUS(status));
i++;
if(i == CREATE_PROCESS_CNT) {
printf("all children had exited\n");
exit(0);
}
}
if(pid == -1) {
perror("waitpid");
exit(1);
}
}
return 0;
}