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信号机制的核心组成部分。

相关推荐
hakukun1 小时前
Ubuntu启动时volume报错无法进入系统问题解决
linux·ubuntu
qq_401700411 小时前
Linux磁盘配置与管理
linux·运维·服务器
hoo3432 小时前
【SolidWorks2025】3D CAD 软件:机械设计安装 + 补丁教程
linux
先知后行。2 小时前
STM32常问问题
linux
Code Warrior3 小时前
【Linux】传输层协议UDP
linux·运维·udp
Evan芙3 小时前
Bash 变量命名规则与类型使用
linux·运维·开发语言·chrome·bash
濊繵4 小时前
Linux网络--Socket 编程 TCP
linux·网络·tcp/ip
menge23334 小时前
Linux网站搭建
linux·运维·网络
Bruce_Liuxiaowei4 小时前
Kali Linux 加入 Windows 域实战指南:解决域发现与加入失败问题
linux·运维·windows
LumenL1u5 小时前
CentOS 7/8/9 上安装 MySQL 8.0+ 完整指南
linux·mysql