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

Linux信号保存与处理机制详解

Linux信号的保存与处理涉及多个关键机制,以下是详细的总结:

1. 信号的保存

  • 进程描述符(task_struct):每个进程的PCB中包含信号相关信息。
    • pending信号集:记录已到达但未处理的信号(未决信号)。每个信号对应一个位,置1表示信号待处理。
    • blocked信号屏蔽字:标识被阻塞(屏蔽)的信号。被屏蔽的信号将暂不递送,直到解除屏蔽。
  • 实时信号队列:实时信号(SIGRTMIN~SIGRTMAX)支持排队,内核为每个进程维护多个队列,确保多次发送的同一信号被依次处理。

2. 信号的处理方式

  • 默认动作:如终止进程(SIGTERM)、忽略(SIGCHLD)或生成核心转储(SIGSEGV)。
  • 忽略信号:通过SIG_IGN显式忽略,但SIGKILL和SIGSTOP不可忽略。
  • 自定义处理函数:用户注册的信号处理函数(通过signal()sigaction()),需注意函数需为异步信号安全。

3. 信号处理流程

  1. 信号产生:通过硬件(如除零)、终端(Ctrl+C)、kill()系统调用等方式触发。
  2. 记录到pending:内核将信号标记在目标进程的pending集合中。
  3. 递送检查:在进程从内核态返回用户态时(如系统调用结束、中断处理完成),检查未被屏蔽的pending信号。
  4. 执行处理函数
    • 内核临时切换到用户态执行处理函数。
    • 处理函数返回后,通过sigreturn系统调用恢复原上下文。
    • 默认情况下,正在处理的信号会被自动阻塞,防止重入。

4. 关键系统调用与函数

  • sigprocmask:修改进程的信号屏蔽字,控制哪些信号被阻塞。
  • sigaction:设置信号处理方式,支持设置SA_RESTART(自动重启被中断的系统调用)及SA_SIGINFO(携带额外信息)。
  • sigpending:获取当前未决的信号集。
  • kill/raise:向进程或自身发送信号。
  • alarm:设置定时器发送SIGALRM。

5. 实时信号 vs 非实时信号

  • 非实时信号(标准信号):如SIGINT、SIGTERM,不支持排队,多次发送可能丢失。
  • 实时信号:通过sigqueue()发送并附带数据,支持可靠排队,确保多次信号被依次处理。

6. 多线程中的信号处理

  • 线程拥有独立的信号屏蔽字,但信号处理函数为进程内共享。
  • 信号可定向到特定线程(如通过pthread_kill()),未处理的信号由主线程处理。

7. 注意事项

  • 可重入性:处理函数应使用异步信号安全函数(如write()),避免调用printf()malloc()等非安全函数。
  • 原子性:通过sig_atomic_t类型变量在信号处理函数与主程序间安全传递状态。
  • 竞态条件:正确处理信号屏蔽与临界区保护,防止条件竞争。

示例场景

#include <signal.h>
#include <stdio.h>
#include <unistd.h>void handler(int sig) {write(STDOUT_FILENO, "Received SIGINT!\n", 17);
}int main() {struct sigaction sa;sa.sa_handler = handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;sigaction(SIGINT, &sa, NULL);while(1) {pause(); // 等待信号}return 0;
}

此代码注册SIGINT的处理函数,按下Ctrl+C时打印消息,处理期间自动阻塞SIGINT,避免递归调用。

总结

理解Linux信号的保存与处理机制,需掌握信号的生命周期(产生、保存、递送)、处理函数的设计约束(可重入性、安全性),以及多线程环境下的复杂性。合理使用信号能提升程序的健壮性,但需谨慎处理异步事件带来的挑战。

相关文章:

  • MySQL 主从同步异常处理
  • 【PySpark安装配置】01 搭建单机模式的PySpark开发环境(Windows系统)
  • 【C++】unordered_set和unordered_map
  • 生信服务器 | 做生信为什么推荐使用Linux服务器?
  • EC2安装WebRTC sdk-c环境、构建、编译
  • 字符串哈希+KMP
  • Android15默认授权浮窗权限
  • 【Android】Android 开发 ADB 常用指令
  • 项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
  • docker容器保存为不依赖基础镜像的独立镜像方法
  • Java中方法调用参数传递机制的理解和示例验证
  • 书籍“之“字形打印矩阵(8)0609
  • 【11408学习记录】考研数学攻坚:行列式本质、性质与计算全突破
  • 【大厂机试题解法笔记】矩阵匹配
  • MySQL JOIN 表过多的优化思路
  • Matlab | 基于matlab的图像去噪的原理及实现
  • ZeenWoman 公司数据结构文档
  • LeetCode - 260. 只出现一次的数字 III
  • 【学习记录】使用 Kali Linux 与 Hashcat 进行 WiFi 安全分析:合法的安全测试指南
  • R语言速释制剂QBD解决方案之二
  • 挂号网站建设/西安seo优化公司
  • 怀柔网站整站优化公司/网站注册流程
  • wordPress主题模板站/关键词优化报价查询
  • 淘宝客网站一定要备案吗/南宁网站seo优化公司
  • 国外自助建站/收录之家
  • 在国外做盗版电影网站吗/百度站长工具排名