wait()
是一个系统调用,用于使父进程等待子进程的终止,并获取子进程的退出状态。它的主要功能可以概括如下:
-
等待子进程终止:
wait()
使父进程暂停执行,直到一个子进程终止。 -
获取子进程的退出状态:通过
wait()
返回的状态值,可以获取子进程的退出状态。 -
子进程回收:当子进程终止后,
wait()
将回收子进程的资源,包括进程表项等。 -
阻塞父进程:如果父进程调用
wait()
时没有终止的子进程,父进程将被阻塞,暂停执行,直到有子进程终止。 -
非阻塞模式:可以使用
WNOHANG
标志来设置非阻塞模式,这样父进程在没有终止的子进程时不会被阻塞,而是立即返回。 -
多子进程管理:
wait()
可以处理多个子进程,但返回的子进程状态是不确定的。
通过使用 wait()
,父进程可以控制和监控子进程的执行,了解子进程的终止状态,并根据需要采取进一步的操作。
在使用 wait()
系统调用时,可以使用一些宏函数来检查子进程的终止状态并从中提取相关信息。下面是这些宏函数的解释:
-
WIFEXITED(status)
:- 用途:检查子进程是否正常终止。
- 返回值:如果子进程正常终止,则返回非零值(真),否则返回 0(假)。
-
WEXITSTATUS(status)
:- 用途:获取子进程的退出状态。
- 参数:
status
是从wait()
或waitpid()
返回的状态值。 - 返回值:如果子进程正常终止,则返回子进程的退出状态。
-
WIFSIGNALED(status)
:- 用途:检查子进程是否被信号终止。
- 返回值:如果子进程被信号终止,则返回非零值(真),否则返回 0(假)。
-
WTERMSIG(status)
:- 用途:获取终止子进程的信号编号。
- 参数:
status
是从wait()
或waitpid()
返回的状态值。 - 返回值:如果子进程被信号终止,则返回终止子进程的信号编号。
这些宏函数对于理解子进程的终止状态和从中提取相关信息非常有用。
下面是一个示例代码,演示了如何使用这些宏函数来检查子进程的终止状态和获取相关信息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
void sys_err(const char* str)
{
perror(str);
exit(1);
}
int main(int argc, char* argv[])
{
pid_t wpid;
int status;
pid_t pid = fork();
if (pid == -1){
sys_err("fork error");
}
else if (pid==0){//子进程操作
printf("-----------child,my id = %d,going to sleep 10s\n",getpid());
sleep(15);
printf("-----------child die----------------\n");
return 73;
}
else if (pid>0){//父进程操作
wpid = wait(&status);
if(wpid==-1){
sys_err("wait error");
}
//判断是否正常结束
if(WIFEXITED(status)){
printf("child exit with %d\n",WEXITSTATUS(status));
}
//判断是否被通过信号量结束
if(WIFSIGNALED(status)){
printf("child kill with signal %d\n",WTERMSIG(status));
}
printf("-----------parent wait finish:%d\n",wpid);
}
printf("=====================end of file\n");
return 0;
}