Linux中父进程通过wait()或waitpid()等待子进程结束,用WIFEXITED、WEXITSTATUS、WIFSIGNALED、WTERMSIG等宏解析status参数:若WIFEXITED为真,WEXITSTATUS返回0–255退出码;若WIFSIGNALED为真,WTERMSIG返回终止信号编号。

在 Linux 中,父进程通过 wait() 或 waitpid() 系统调用等待子进程结束,并利用 WIFEXITED、WEXITSTATUS、WIFSIGNALED、WTERMSIG 等宏来解析子进程的终止状态(即 `status` 参数),从而判断其是正常退出还是被信号终止,并获取具体退出码或终止信号。
理解 wait() 的 status 参数和核心宏
调用 wait(&status) 后,`status` 是一个整数,其低 16 位编码了子进程的退出信息。直接读取 `status` 没有意义,必须用标准宏解码:
-
WIFEXITED(status):返回非零值,表示子进程是 正常退出(即执行了
exit()、return或 main 函数结束) -
WEXITSTATUS(status):仅在
WIFEXITED(status)为真时有效,返回子进程传给exit()的低 8 位退出码(0–255) -
WIFSIGNALED(status):返回非零值,表示子进程是 被信号终止(如
kill -9、段错误等) -
WTERMSIG(status):仅在
WIFSIGNALED(status)为真时有效,返回导致终止的信号编号(如 11 表示 SIGSEGV)
典型 C 代码逻辑判定示例
以下是一个完整、安全的父进程等待并分类处理子进程退出状态的片段:
pid_t pid = fork();
if (pid == 0) {
// 子进程
exit(42); // 或 execl("/bin/ls", "ls", "-l", NULL);
} else if (pid > 0) {
int status;
pid_t w = wait(&status);
if (w == -1) {
perror("wait");
return 1;
}
<pre class="brush:php;toolbar:false;">if (WIFEXITED(status)) {
int exit_code = WEXITSTATUS(status);
printf("子进程正常退出,退出码:%d\n", exit_code);
if (exit_code == 0) {
printf("→ 任务成功\n");
} else if (exit_code == 1) {
printf("→ 输入参数错误\n");
} else {
printf("→ 其他业务错误\n");
}
} else if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
printf("子进程被信号 %d 终止(%s)\n", sig, strsignal(sig));
if (sig == SIGSEGV) {
printf("→ 发生段错误,检查内存访问\n");
}
}}
注意点与常见误区
-
status 必须初始化:未初始化的 `int status` 可能含随机值,导致宏判断出错;建议声明为
int status = 0; -
不要直接比较 status == N:比如
if (status == 0)是错误的,因为 `status` 不是退出码本身,而是编码后的整数 -
WEXITSTATUS 返回的是 0–255 范围内的值:即使子进程调用
exit(-1),实际取到的是 255(补码截断) -
waitpid() 更灵活:可用
waitpid(pid, &status, 0)等待指定子进程;加WNOHANG实现非阻塞等待
Shell 中的对应机制(辅助理解)
Linux Shell 的 `$?` 变量本质就是上一条命令的 `WEXITSTATUS(status)` 值。例如:
$ false; echo $? # 输出 1 $ true; echo $? # 输出 0 $ kill -SEGV $$; echo $? # 通常不会执行到这里,但若子 shell 被终止,父 shell 可能收到非零退出码
Shell 内部正是通过 wait() + WIFEXITED/WEXITSTATUS 实现这一行为。











