wait() 与waitpid()函数的定义
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options );
功能描述
这两个系统调用被用来等待被调用的子进程的状态发生改变,并获取状态已经改变的子进程的信息。如果一个子进程的状态已经发生改变,那么这些调用就会立即返回。否则,他们将会阻塞直到任意一个子进程状态发生改变,或者一个信号处理程序中断了这次调用(假设系统调用不会使用信号处理程序(2)的SA_RESTART标志自动重新启动)。
状态改变有三种情况:
1.子进程中止
2.子进程被信号中断
3.子进程被信号恢复 在子进程中止的情况下,执行wait函数,系统会释放子进程的资源;如果不调用wait函数,那么正常退出的子进程就会变成“僵尸”状态。
参数解析
pid_t pid
参数pid为欲等待的子进程的识别码,其具体含义如下:
pid | 说明 |
---|---|
pid < -1 | 等待进程组号为pid绝对值的任何子进程 |
pid = -1 | 等待任何子进程 |
pid = 0 | 等待进程组号与当前进程相同的任何子进程 |
pid > 0 | 等待进程号为pid的子进程 |
int *wststus
指针,指向的空间用来保存子进程退出信息(怎么死的,退出码等),退出信息保存在一个整数中,低8位用来保存退出码,其余的位用来保存一些其他退出信息。
宏 | 说明 |
---|---|
WIFEXITED(wstatus) | 如果子进程正常结束,即调用exit(3)或_exit(2),或从main()返回,则返回true |
WEXITSTATUS(wstatus) | 返回子进程的退出状态。它由子进程在调用exit(3)或_exit(2)时指定的状态参数的最低有效8位组成,或者作为main()中return语句的参数。只有当WIFEXITED返回true时,使用这个宏才有意义。 |
WIFSIGNALED(wstatus) | 如果子进程被信号终止,则返回true |
WTERMSIG(wstatus) | 如果WIFSIGNALED(wstatus)返回true,则可以用该宏获得导致子进程终止的信号代码 |
WIFSTOPPED(wstatus) | 如果当前子进程被暂停了,则返回true |
WSTOPSIG(wstatus) | 如果WIFSTOPPED(wstatus)返回true,则可以使用该宏获得导致子进程暂停的信号代码 |
WCOREDUMP(wstatus) | returns true if the child produced a core dump. This macro should be employed only if WIFSIGNALED returned true.This macro is not specified in POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS). Therefore, enclose its use inside #ifdef WCOREDUMP … #endif. |
WIFCONTINUED(wstatus) | (since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT. |
int options
参数options提供了一些另外的选项来控制waitpid()函数的行为。如果不想使用这些选项,则可以把这个参数设为0
宏 | 说明 |
---|---|
WNOHANG | 不阻塞等待,如果没有子进程退出就立即返回 |
WUNTRACED | 如果子进程已经停止(但是没有通过ptrace(2)跟踪),也会返回。即使没有指定此选项,也会提供已停止的跟踪子进程的状态。 |
WCONTINUED | 如果子进程被信号终止,则返回true |
wait(&status);
waitpid(-1, &status, 0);
所以调用wait(&status)等价于waitpid(-1, &status, 0)
pid_t
返回值: 成功返回退出的那个子进程的进程PID;失败返回-1,同时errno被设置
示例
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
pid_t pid;
pid = fork();
if(pid == 0)
{
return -1;
}
else if(pid > 0)
{
int status;
wait(&status);
if(WIFEXITED(status))
{
printf("child's exit code : %d\n",WEXITSTATUS(status));
}
}
else
{
perror("fork error");
return -1
}
}
在子进程正常退出的情况下,即WIFEXITED(status)为真时,在父进程里调用,打印WEXITSTATUS(status)出子进程的退出码,-1–>255(8bit)