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

【Linux复习】:进程信号

进程信号

信号概念与本质

信号是软件中断,用来异步通知进程某个事件已发生。
会打断进程当前执行流程,让它转去处理信号。
进程对每个信号都有默认处理方式:忽略、捕获、终止、 core dump 等。
内核在进程的 task_struct 里,用 ** 信号位图(pending 信号集)** 标记 “有信号到达”,

信号种类

非可靠信号
1-31
支持信号丢失:多个相同信号同时发来,可能只触发一次
不排队,只标记 “有 / 没有”
可靠信号
34-64
支持排队,发多少次就处理多少次,不会丢失
有优先级,值越大优先级越高

信号生命周期

信号的产生

本质:操作系统给进程发送一个 “事件通知”
硬件来源
键盘:Ctrl+C→SIGINT、Ctrl+\→SIGQUIT
硬件异常:除零、非法内存访问 → OS 发 SIGFPE、SIGSEGV
软件来源
系统调用:kill、raise、abort
软件条件:alarm 超时 → SIGALRM;管道破裂 → SIGPIPE

信号在进程中注册

注册
内核在进程的 task_struct 中,为该信号绑定处理函数指针
相当于:handler[signo] = 自定义函数
注销
把信号的处理方式恢复成默认或忽略
并不是把信号删掉,而是取消自定义捕捉

信号的处理

三种处理方式

  1. 默认处理(SIG_DFL)
    终止、暂停、忽略、Core Dump 等
  2. 忽略处理(SIG_IGN)
    直接丢掉,不做任何事
  3. 自定义捕捉
typedefvoid(*sighandler_t)(int);

自己写函数,信号来时跳转执行
修改处理方式的接口
signal

signal(SIGINT,handler);

signaction

structsigactionact;act.sa_handler=handler;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);

用户态 ↔ 内核态切换
用户态:受限,只能访问自己资源
内核态:高权限,可管理硬件、进程、信号
信号处理流程:
用户态运行 → 收到信号 → 陷入内核 → 选择处理函数 → 切回用户态执行自定义函数 → 再回内核 → 恢复原执行流

信号的保存

信号递达:信号准备被处理,处理方式有:默认,忽略,自定义
信号未决:信号传输成功但还未处理这个状态
信号阻塞:表示信号被阻塞,信号不会被识别
blocked 位图:阻塞信号集
pending 位图:未决信号集
handler:递达信号集

信号的阻塞

原理
在内核的 blocked 信号位图中标记对应位为 1
→ 该信号暂时不被处理,一直停留在 pending
实现接口

sigprocmask(how,&set,&oldset);

可设置:阻塞、解阻塞、替换阻塞信号集

函数可重入与不可重入

函数可重入
定义:在多个执行流(信号处理函数 / 线程)中同时调用,不会出现数据混乱、安全问题
特点:
不访问全局变量、静态变量
不使用malloc/free
不调用不可重入函数
只使用局部变量、函数参数
信号安全:信号处理函数中只能调用可重入函数
不可重入函数
访问全局 / 静态变量、使用 malloc、调用库函数
多执行流同时调用 → 数据错乱、逻辑崩溃
绝对不能在信号处理函数中使用

volatile

作用

  1. 保持内存可见性
    告诉编译器:不要优化这个变量,每次都从内存读取,不要用寄存器缓存
  2. 防止过度优化
    避免编译器自作主张删除代码、缓存值,导致程序逻辑错误
    使用场景
    信号处理函数中修改的全局变量
    多线程共享变量
    硬件寄存器访问

信号的相关操作

// 1. 信号集初始化intsigemptyset(sigset_t*set);// 清空信号集,所有位0intsigfillset(sigset_t*set);// 填满信号集,所有位1// 2. 信号集增删查intsigaddset(sigset_t*set,intsignum);// 添加一个信号intsigdelset(sigset_t*set,intsignum);// 删除一个信号intsigismember(constsigset_t*set,intsignum);// 判断信号是否在集合中// 3. 设置信号阻塞(核心!)intsigprocmask(inthow,constsigset_t*restrict set,sigset_t*restrict oset);// how:SIG_BLOCK(阻塞) / SIG_UNBLOCK(解阻塞) / SIG_SETMASK(覆盖)// 4. 获取未决信号intsigpending(sigset_t*set);// 读取当前pending信号集// 5. 修改信号处理方式(现代、安全)intsigaction(intsig,conststructsigaction*restrict act,structsigaction*restrict oact);// 6. 修改信号处理方式(老式、简单)void(*signal(intsig,void(*func)(int)))(int);

核心转储

定义
程序崩溃时,操作系统把进程内存数据保存到 core 文件,用于调试崩溃原因
特点
存储:崩溃时的内存、寄存器、调用栈
作用:快速定位崩溃代码(gdb 调试)
默认关闭:文件太大、占用磁盘

http://www.jsqmd.com/news/608778/

相关文章:

  • Qwen2-VL-2B多模态向量模型教程:图文嵌入向量用于多标签图像分类迁移学习
  • RFID智能柜-RFID智能柜厂家推荐 - 聚澜智能
  • Dell R720服务器安装Ubuntu避坑指南:从BIOS设置到分区优化全流程
  • Nginx本地缓存API
  • 程序控制结构
  • Altium AD20差分对走线实战:如何用交互式布线快速搞定高速信号线
  • ABAQUS用户子程序进阶指南——UMAT参数详解与实战配置
  • 通俗秒懂:储能控制器在电网调频中的关键作用与实现原理
  • 软件需求工程教案
  • Golang如何设置HTTP路由_Golang HTTP路由教程【实用】
  • 一张图看懂巴菲特 48 年投资帝国:知识图谱效果全展示
  • 别再手动配环境了!用ModelScope官方镜像5分钟搞定AI模型运行环境(附最新CPU/GPU镜像地址)
  • 【转载】ROS 中 CMakeLists.txt 文件使用的讲解与总结
  • Workstation 避坑指南:网络总连不上?深度解析常见网络配置故障与底层排错逻辑
  • 【计算机网络八股】【欧弟求职】TCP相关
  • 一台服务器跑4个独立站,我是怎么做到的?
  • 魔兽争霸III终极优化指南:免费解决老游戏在现代电脑的兼容性问题
  • RFID智能柜-RFID智能柜公司推荐 - 聚澜智能
  • 如何用 every 判断数组是否所有元素都满足特定条件
  • Spring AI 1.x 系列【25】结构化输出案例演示
  • XOutput完整指南:如何将旧游戏手柄转换为Xbox控制器
  • GeoAI赋能智慧城市:从交通优化到环境监测的实战解析
  • 别再只用‘auto’模式了!深入Halcon条码识别参数:手把手教你调优barcode_width_min与扫描线提升识别率
  • ZYNQ FPGA固化文件生成与烧录全流程详解
  • Springboot 实现多数据源(PostgreSQL 和 SQL Server)连接康
  • 基于改进A*算法与DWA融合策略的机器人路径规划仿真研究:全局规划与局部避障的综合性能分析
  • c++如何利用C++23的std--expected重构文件操作的错误检查代码【实战】
  • Node Modules Inspector:可视化你的Node.js依赖关系,5分钟快速上手指南
  • 电容滤波实战:如何为你的MCU电源选择100nf和1uf电容组合?
  • 企业级 Agent 治理平台:公司用数字帮手的必备管家