我们可以通过系统写好的宏来获取获取进程的退出码或退出信号:底层是通过对 waitpid 函数参数 status 进行位运算,取对应部分的数值
一、相关宏定义的介绍
waitpid(pid, &status, 0);
:
- 这行代码等待指定 PID (
pid
) 的子进程结束,并将子进程的退出状态存储在status
变量中。
一共三组相关宏定义:
第一组:
-
WIFEXITED(status)
:- 检查
status
是否表示子进程通过正常的exit
或_exit
系统调用退出。如果是,返回非零值。
- 检查
-
WEXITSTATUS(status)
:- 如果
WIFEXITED(status)
返回真,则WEXITSTATUS(status)
用于提取子进程的退出码。
- 如果
第二组:
WIFSIGNALED(status)
:- 检查
status
是否表示子进程因接收到信号而异常终止。如果是,返回非零值。
- 检查
WTERMSIG(status)
:- 如果
WIFSIGNALED(status)
返回真,则WTERMSIG(status)
用于提取终止子进程的信号编号。
- 如果
第三组:
WIFSTOPPED(status)
:- 检查
status
是否表示子进程被信号停止。如果是,返回非零值。
- 检查
WSTOPSIG(status)
:- 如果
WIFSTOPPED(status)
返回真,则WSTOPSIG(status)
用于提取停止子进程的信号编号。
- 如果
二、概括:方便直观理解用法
进程退出有三种情况
1、正常退出 :通过 exit
和 _exit
函数退出进程
2、被信号异常终止:
在运行过程中,如果进程遇到了无法处理的错误或异常,操作系统向该进程发送一个信号终止该进程
3、被信号停止:
并非真正终止进程,而是因某种需求暂时让进程停下
这类宏有两类作用
1、确认进程退出是哪种情况(是上面三种进程退出中的哪种)
2、获取目标信息
目的:先确认是哪种退出情况,再通过相应的宏获取想要的信息
例如第一组
cpp
// 检查子进程是否正常退出
if (WIFEXITED(status)) {
int exit_code = WEXITSTATUS(status);
printf("子进程正常退出,退出码为: %d\n", exit_code);
}
WIFEXITED
:Weather if exited
:检查 是否 正常退出 (即进程退出的第一种情况)
WEXITSTATUS
:Wait exit status
:获取退出状态码
其他两组宏也是如此
三、具体使用样例
c++
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main() {
pid_t pid = fork();
if (pid == 0) { // 子进程
// 子进程执行一些操作后退出
exit(3);
}
else if (pid > 0) { // 父进程
int status;
// 等待子进程结束
waitpid(pid, &status, 0);
// 检查子进程是否正常退出
if (WIFEXITED(status)) {
int exit_code = WEXITSTATUS(status);
printf("子进程正常退出,退出码为: %d\n", exit_code);
}
else if (WIFSIGNALED(status)) {
int signal_number = WTERMSIG(status);
printf("子进程因信号 %d 异常终止\n", signal_number);
}
else if (WIFSTOPPED(status)) {
int stop_signal = WSTOPSIG(status);
printf("子进程被信号 %d 停止\n", stop_signal);
}
else {
printf("子进程的状态未知\n");
}
}
else {
// fork 失败
perror("fork");
}
return 0;
}
四、拆解宏的命名:方便记忆
WIFEXITED(status)
WIFSIGNALED(status)
WIFSTOPPED(status)
这类宏通常以 WIF
开头,表示 "Whether IF",即 "是否"。这里的 "IF" 并不是传统意义上的 "if"(如果),而是一种约定,用来指示这是一个条件判断宏,用于检查某个特定的状态是否成立。
WIF
表示 "Whether IF",即 "是否"。- 后面的部分表示具体的条件
EXITED
表示正常退出:exitedSIGNALED
表示因信号终止:signaledSTOPPED
表示被信号停止:stopped
WEXITSTATUS(status)
WTERMSIG(status)
WSTOPSIG(status)
W
在这些宏中通常表示 "Wait" 相关的函数或宏:如wait 函数
、waitpid 函数
- 后面的部分表示具体的要获取的信息,如
EXITSTATUS
提取子进程的实际退出码:exit statusTERMSIG
提取导致子进程终止的信号编号:terminal signalSTOPSIG
提取导致子进程停止的信号编号:stop signal