Linux 信号处理标志sa_flags详解

这些宏定义是 Linux 内核中用于 sigaction 结构体 sa_flags 字段的标志位,用于控制信号处理的行为。它们位于内核源码的 include/uapi/asm-generic/signal-defs.h 文件中。以下是每个标志的详细解释:

信号处理标志详解

  1. SA_NOCLDSTOP (0x00000001)

    • 含义 :当子进程停止或恢复时,不产生 SIGCHLD 信号
    • 用途
      默认情况下,当子进程停止(SIGSTOP)或恢复(SIGCONT)时,父进程会收到 SIGCHLD 信号。设置此标志后,内核不会在这些情况下发送 SIGCHLD
  2. SA_NOCLDWAIT (0x00000002)

    • 含义:子进程退出时不创建僵尸进程
    • 用途
      当设置此标志时,内核会在子进程终止时立即清理其资源,而不是使其成为僵尸进程。父进程调用 wait() 将立即返回错误。
  3. SA_SIGINFO (0x00000004)

    • 含义:使用扩展信号处理函数

    • 用途
      表示信号处理函数有三个参数:

      c 复制代码
      void handler(int sig, siginfo_t *info, void *context)

      其中 siginfo_t 包含发送信号的进程PID、UID等详细信息。

  4. SA_THIRTYTWO (0x02000000)

    • 含义:恢复32位信号处理语义(历史遗留)
    • 用途
      在64位系统上保持与旧32位信号处理的兼容性,现代代码通常不需要使用。
  5. SA_RESTORER (0x04000000)

    • 含义:使用信号恢复函数
    • 用途
      表示 sigaction 结构体中指定了 sa_restorer 函数,用于信号处理完成后恢复上下文(主要用于兼容性)。
  6. SA_ONSTACK (0x08000000)

    • 含义:使用备选信号栈
    • 用途
      当设置此标志时,信号处理函数将在 sigaltstack() 设置的备选栈上执行,防止栈溢出导致信号无法处理。
  7. SA_RESTART (0x10000000)

    • 含义:被信号中断的系统调用自动重启
    • 用途
      如果系统调用被信号中断,内核会自动重启该系统调用而不是返回 EINTR 错误。
  8. SA_NODEFER (0x40000000)

    • 含义:不阻塞当前信号
    • 用途
      默认情况下,当信号处理函数执行时,内核会自动阻塞相同信号。此标志允许信号处理函数被自身信号中断(可重入)。
  9. SA_RESETHAND (0x80000000)

    • 含义:信号处理完成后重置为默认操作
    • 用途
      信号第一次触发时执行自定义处理函数,之后自动重置为默认行为(如 SIG_DFL)。

兼容性别名

c 复制代码
#define SA_NOMASK    SA_NODEFER   // 同 SA_NODEFER
#define SA_ONESHOT   SA_RESETHAND // 同 SA_RESETHAND
  • 这些是为了保持与旧代码的兼容性而定义的别名

典型用法示例

c 复制代码
#include <signal.h>

void signal_handler(int sig) {
    // 信号处理逻辑
}

int main() {
    struct sigaction sa;
    
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);  // 初始化信号掩码
    
    // 设置标志:自动重启 + 使用备选栈 + 不阻塞自身信号
    sa.sa_flags = SA_RESTART | SA_ONSTACK | SA_NODEFER;
    
    sigaction(SIGINT, &sa, NULL);  // 注册SIGINT处理
    
    // ...程序主循环...
    return 0;
}

内核实现位置

这些标志位在内核的信号处理流程中被使用,主要涉及:

  1. 信号发送kernel/signal.c 中的 send_signal() 函数
  2. 信号处理arch/x86/kernel/signal.c 中的 handle_signal() 函数
  3. 信号栈管理kernel/signal.c 中的 get_sigframe() 函数

这些标志位通过 sigaction 系统调用从用户空间传递到内核空间,控制内核的信号处理行为,是Linux信号机制的核心组成部分。

相关推荐
YuCaiH2 分钟前
Linux文件处理
linux·笔记·嵌入式
sulikey12 分钟前
从实验出发深入理解Linux目录权限:r、w、x分别控制什么?能否进入目录到底由谁决定?
linux·运维·服务器·ubuntu·centos
疯狂吧小飞牛24 分钟前
ip rule 策略路由
linux·网络·tcp/ip·运维开发
缘友一世38 分钟前
深入理解Shell与反弹Shell:从原理到实战
linux·网络安全·shell
stark张宇1 小时前
网络排错全流程:从DNS解析到防火墙,逐层拆解常见问题
linux·网络协议·dns
望获linux4 小时前
【实时Linux实战系列】实时 Linux 的自动化基准测试框架
java·大数据·linux·运维·网络·elasticsearch·搜索引擎
纸带4 小时前
USB --SETUP --STATUS阶段
linux·服务器·网络
---学无止境---4 小时前
Linux中初始化空循环次数和pid位图初始化
linux
东城绝神6 小时前
《Linux运维总结:基于X86_64+ARM64架构CPU使用docker-compose一键离线部署consul 1.21.5容器版集群》
linux·运维·docker·架构·consul
ajassi20006 小时前
开源 Linux 服务器与中间件(三)服务器--Nginx
linux·服务器·开源