当前位置: 首页 > news >正文

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)
  • 目的:临时阻止信号递送
  • 实现
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigprocmask(SIG_BLOCK, &mask, NULL);  // 阻塞SIGINT
    
  • 特点
    • 被阻塞的信号处于**挂起(Pending)**状态
    • sigpending() 可获取挂起信号集
    • 解除阻塞后立即递送
(2) 信号屏蔽(Masking)
  • 执行处理函数时自动生效
    • 当前处理的信号自动被屏蔽(除非设置 SA_NODEFER
    • 通过 sa_mask 指定额外屏蔽的信号集
  • 作用:防止信号处理函数被重入

4. 信号处理模型

(1) 单次处理模型
struct sigaction sa = {.sa_handler = handler,.sa_flags = SA_RESETHAND  // 处理一次后恢复默认行为
};
  • 特点:类似传统 signal() 的行为
  • 风险:信号再次发生时可能触发默认行为(如终止进程)
(2) 持久处理模型
struct sigaction sa = {.sa_handler = handler,.sa_flags = 0  // 持续有效
};
  • 特点:处理函数保持激活状态
  • 最佳实践:配合信号阻塞使用
(3) 实时信号处理模型
struct sigaction sa = {.sa_sigaction = rt_handler,.sa_flags = SA_SIGINFO | SA_RESTART
};
  • 特点
    • 支持信号排队(避免丢失)
    • 可携带附加信息(发送者PID、错误地址等)
    • 使用 sigqueue() 发送:
    union sigval value = {.sival_int = 42};
    sigqueue(pid, SIGRTMIN+1, value);
    

5. 关键系统调用

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

6. 特殊处理场景

(1) 系统调用中断处理
  • 问题:慢速系统调用(如 read())被信号中断
  • 解决方案
    struct sigaction sa = {.sa_handler = handler,.sa_flags = SA_RESTART  // 自动重启被中断的系统调用
    };
    
(2) 信号竞争处理
  • 临界区保护模式
    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) 子进程终止处理
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. 自包含状态

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

    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 信号处理的完整模型,开发者需要理解其交互机制才能编写出健壮可靠的信号处理代码。

http://www.lryc.cn/news/611533.html

相关文章:

  • 外观模式(Facade Pattern)及其应用场景
  • Leetcode-3488距离最小相等元素查询
  • 系统的缓存(buff/cache)是如何影响系统性能的?
  • 第五十篇:AI画家的“神经中枢”:ComfyUI的推理路径与缓存逻辑深度解析
  • 【Web安全】csrf、ssrf和xxe的区别
  • Python实现电商商品数据可视化分析系统开发实践
  • Qt 中实现多线程的两种方式及结合
  • Pytest项目_day05(requests加入headers)
  • 8.6 JavaWeb(请求响应 P67-P74)
  • 部署Web UI自动化测试平台:SeleniumFlaskTester
  • UI测试平台TestComplete的AI视觉引擎技术解析
  • QT+opencv+yolov8推理
  • 移动端跨平台框架(支持Harmony、iOS、Android)
  • C语言:指针(1-2)
  • Kaggle 经典竞赛泰坦尼克号:超级无敌爆炸详细基础逐行讲解Pytorch实现代码,看完保证你也会!!!
  • 霍尔传感器
  • 碰撞问题的分析
  • 什么是CDN, 它为什么更快
  • 《算法导论》第 7 章 - 快速排序
  • 概率/期望 DP Jon and Orbs
  • 机器学习④【算法详解:从决策树到随机森林】
  • 一周学会Matplotlib3 Python 数据可视化-图形的组成部分
  • 场外期权的卖方是什么策略?
  • Python包管理新利器:uv全面解析与Conda对比指南
  • 从 LinkedIn 到 Apache:Kafka 的架构设计与应用场景
  • KafKa 项目 -- GitHub 学习
  • 【第6话:相机模型2】相机标定在自动驾驶中的作用、相机标定方法详解及代码说明
  • 在Word和WPS文字中如何输入汉字的偏旁部首
  • SELinux加固Linux安全2
  • docker安装FFmpeg