Unix/Linux 系统编程中用于管理信号处理行为的核心概念或模型

在 Unix/Linux 系统编程中,管理信号处理行为涉及以下核心概念和模型,它们共同构成了信号处理的框架:


1. 信号(Signal)模型

  • 软件中断:信号是异步事件通知机制,类比硬件中断
  • 预定义类型SIGINT (Ctrl+C)、SIGTERM (终止请求)、SIGSEGV (段错误) 等标准信号
  • 生命周期
    1. 生成(Generation):事件触发信号产生
    2. 递送(Delivery):内核将信号传递给目标进程
    3. 处理(Handling):进程执行注册的处理动作

2. 信号处理行为控制

行为类型 说明 设置方式
默认行为 系统预定义行为(终止/忽略/暂停) SIG_DFL
忽略信号 丢弃信号不做任何响应 SIG_IGN
自定义处理函数 用户注册的信号处理例程 函数指针

3. 关键控制机制

(1) 信号阻塞(Blocking)
  • 目的:临时阻止信号递送

  • 实现

    c 复制代码
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigprocmask(SIG_BLOCK, &mask, NULL);  // 阻塞SIGINT
  • 特点

    • 被阻塞的信号处于**挂起(Pending)**状态
    • sigpending() 可获取挂起信号集
    • 解除阻塞后立即递送
(2) 信号屏蔽(Masking)
  • 执行处理函数时自动生效
    • 当前处理的信号自动被屏蔽(除非设置 SA_NODEFER
    • 通过 sa_mask 指定额外屏蔽的信号集
  • 作用:防止信号处理函数被重入

4. 信号处理模型

(1) 单次处理模型
c 复制代码
struct sigaction sa = {
    .sa_handler = handler,
    .sa_flags = SA_RESETHAND  // 处理一次后恢复默认行为
};
  • 特点 :类似传统 signal() 的行为
  • 风险:信号再次发生时可能触发默认行为(如终止进程)
(2) 持久处理模型
c 复制代码
struct sigaction sa = {
    .sa_handler = handler,
    .sa_flags = 0  // 持续有效
};
  • 特点:处理函数保持激活状态
  • 最佳实践:配合信号阻塞使用
(3) 实时信号处理模型
c 复制代码
struct sigaction sa = {
    .sa_sigaction = rt_handler,
    .sa_flags = SA_SIGINFO | SA_RESTART
};
  • 特点

    • 支持信号排队(避免丢失)
    • 可携带附加信息(发送者PID、错误地址等)
    • 使用 sigqueue() 发送:
    c 复制代码
    union sigval value = {.sival_int = 42};
    sigqueue(pid, SIGRTMIN+1, value);

5. 关键系统调用

系统调用 用途
sigaction() 注册信号处理行为(核心接口)
sigprocmask() 控制进程信号屏蔽集
sigsuspend() 原子操作:设置屏蔽集 + 等待信号
kill()/raise() 发送信号(跨进程/自身)
sigaltstack() 设置备选信号栈(处理栈溢出信号)

6. 特殊处理场景

(1) 系统调用中断处理
  • 问题 :慢速系统调用(如 read())被信号中断

  • 解决方案

    c 复制代码
    struct sigaction sa = {
        .sa_handler = handler,
        .sa_flags = SA_RESTART  // 自动重启被中断的系统调用
    };
(2) 信号竞争处理
  • 临界区保护模式

    c 复制代码
    sigset_t new_mask, old_mask;
    sigemptyset(&new_mask);
    sigaddset(&new_mask, SIGINT);
    
    // 进入临界区前阻塞信号
    sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
    
    /* 临界区代码(不会被SIGINT中断) */
    
    // 等待可能发生的信号
    sigsuspend(&old_mask);
    
    // 恢复原始屏蔽集
    sigprocmask(SIG_SETMASK, &old_mask, NULL);
(3) 子进程终止处理
c 复制代码
void sigchld_handler(int sig) {
    while (waitpid(-1, NULL, WNOHANG) > 0); // 非阻塞回收所有僵尸进程
}

// 注册处理
struct sigaction sa = {
    .sa_handler = sigchld_handler,
    .sa_flags = SA_RESTART | SA_NOCLDSTOP
};
sigaction(SIGCHLD, &sa, NULL);

7. 安全编程模型

  1. 异步信号安全(Async-signal-safe):

    • 信号处理函数中只能调用 异步安全函数(如 write(), _exit()
    • 禁止调用 非可重入函数(malloc, printf 等)
  2. 自包含状态

    c 复制代码
    volatile sig_atomic_t flag = 0;  // 信号安全标志
    
    void handler(int sig) {
        flag = 1;  // 仅设置标志,主循环中处理
    }
  3. 备选信号栈

    c 复制代码
    stack_t ss = {
        .ss_sp = malloc(SIGSTKSZ), 
        .ss_size = SIGSTKSZ
    };
    sigaltstack(&ss, NULL);  // 设置备选栈
    
    struct sigaction sa = {
        .sa_handler = handler,
        .sa_flags = SA_ONSTACK  // 使用备选栈
    };

概念关系图

复制代码
+---------------------+
|   信号产生源         | (硬件/内核/进程)
+----------+----------+
           | 生成信号
           v
+---------------------+
|   内核信号队列       | (实时信号排队)
+----------+----------+
           | 递送决策
           v
+---------------------+  阻塞?   +----------+
|   进程信号屏蔽集     +--------->| 挂起状态 |
+----------+----------+          +----------+
           | 未阻塞?
           v
+---------------------+
|   信号处理分发       |
|  +----------------+ |
|  | 默认行为处理    | |
|  | 忽略信号       | |
|  | 自定义处理函数  | |
|  +----------------+ |
+---------------------+
           |
           v
+---------------------+
|   处理函数执行环境   |
|  - 自动信号屏蔽     |
|  - 备选信号栈       |
|  - 中断系统调用     |
+---------------------+

这些核心概念共同构成了 Unix/Linux 信号处理的完整模型,开发者需要理解其交互机制才能编写出健壮可靠的信号处理代码。

相关推荐
__Smile°20 分钟前
Gitlab+Jenkins+K8S+Registry 建立 CI/CD 流水线
linux·ci/cd·docker·kubernetes·gitlab·jenkins
千里镜宵烛39 分钟前
互斥锁与条件变量
linux·开发语言·c++·算法·系统架构
AI 嗯啦2 小时前
linux的用户操作(详细介绍)
linux·运维·服务器
AOwhisky2 小时前
云计算一阶段Ⅱ——12. SELinux 加固 Linux 安全
linux·安全·云计算
Ronin3052 小时前
【Linux系统】进程间通信:命名管道
linux·服务器·命名管道
东东今天敲代码了吗2 小时前
Ubuntu20.04 离线安装 FFmpeg 静态编译包
linux·运维·服务器·ubuntu·ffmpeg
The god of big data2 小时前
最新教程 | CentOS 7 下 MySQL 8 离线部署完整手册(含自动部署脚本)
linux·mysql·centos
tjjingpan3 小时前
HCIP-Datacom Core Technology V1.0_6 IS-IS原理和配置
linux·运维·服务器
努力努力再努力wz4 小时前
【Linux内核系列】:信号(上)
java·linux·运维·服务器·c语言·开发语言·c++