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

相关推荐
C语言小火车9 小时前
嵌入式Linux应用开发技术栈完全指南
linux·运维·服务器
天南散修10 小时前
MT7916驱动中802.11转换为802.3
linux·网络·驱动开发·wifi·802.11
CriticalThinking10 小时前
在xshell中使用ssh隧道访问远程服务
linux·网络·ssh
爱装代码的小瓶子10 小时前
安工大题目分类(含解析和翻译)
linux·网络·c
是个西兰花11 小时前
linux:命名管道与共享内存
linux·运维·服务器·网络·c++
Snasph11 小时前
Linux 日志流水线深度解析:syslog() → journald → rsyslog → /var/log/syslog
linux·syslog·rsyslog
凡人叶枫12 小时前
Effective C++ 条款08:别让异常逃离析构函数
java·linux·数据库·c++·嵌入式开发
新时代牛马12 小时前
内核调试方法
linux·学习
墨痕诉清风12 小时前
Linux系统设置上海时间(24小时制)
linux·运维·服务器
utf8mb4安全女神12 小时前
脚本模块化
linux·运维·服务器