【Linux】如何通过系统宏定义,获取进程的退出码或退出信号

我们可以通过系统写好的宏来获取获取进程的退出码或退出信号:底层是通过对 waitpid 函数参数 status 进行位运算,取对应部分的数值

一、相关宏定义的介绍

waitpid(pid, &status, 0);

  • 这行代码等待指定 PID (pid) 的子进程结束,并将子进程的退出状态存储在 status 变量中。

一共三组相关宏定义:

第一组:

  1. WIFEXITED(status)

    • 检查 status 是否表示子进程通过正常的 exit_exit 系统调用退出。如果是,返回非零值。
  2. WEXITSTATUS(status)

    • 如果 WIFEXITED(status) 返回真,则 WEXITSTATUS(status) 用于提取子进程的退出码。

第二组:

  1. WIFSIGNALED(status)
    • 检查 status 是否表示子进程因接收到信号而异常终止。如果是,返回非零值。
  2. WTERMSIG(status)
    • 如果 WIFSIGNALED(status) 返回真,则 WTERMSIG(status) 用于提取终止子进程的信号编号。

第三组:

  1. WIFSTOPPED(status)
    • 检查 status 是否表示子进程被信号停止。如果是,返回非零值。
  2. 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);
} 

WIFEXITEDWeather if exited :检查 是否 正常退出 (即进程退出的第一种情况)
WEXITSTATUSWait 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 表示正常退出:exited
    • SIGNALED 表示因信号终止:signaled
    • STOPPED 表示被信号停止:stopped

WEXITSTATUS(status)

WTERMSIG(status)

WSTOPSIG(status)

  • W 在这些宏中通常表示 "Wait" 相关的函数或宏:如 wait 函数waitpid 函数
  • 后面的部分表示具体的要获取的信息,如
    • EXITSTATUS 提取子进程的实际退出码:exit status
    • TERMSIG 提取导致子进程终止的信号编号:terminal signal
    • STOPSIG 提取导致子进程停止的信号编号:stop signal

相关推荐
Johny_Zhao1 天前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
chlk1233 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑3 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件3 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号3 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash3 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI4 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行4 天前
Linux和window共享文件夹
linux
木心月转码ing5 天前
WSL+Cpp开发环境配置
linux
崔小汤呀6 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端