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

【Linux内核】Linux信号机制

Linux 信号机制的底层原理是内核通过中断式通知实现进程间 / 内核与进程间的事件传递,本质是对 “异常事件” 的异步处理机制。其核心流程涉及信号的产生、在内核中的管理、向进程的递送,以及进程对信号的处理四个阶段,底层依赖 CPU 中断、进程上下文切换和内核数据结构的协作。

信号可以理解为 “软件层面的中断”,信号则是内核或其他进程通过 “软件指令” 通知目标进程 “发生了特定事件”,迫使进程暂停当前操作,优先处理信号。例如用户按下Ctrl+C时,终端驱动会向进程发送SIGINT信号,内核会暂停进程的正常执行,转去执行SIGINT对应的处理逻辑(默认是终止进程)

信号的生命周期

信号的底层运作可拆解为四个关键阶段,每个阶段依赖内核的特定机制和数据结构

  1. 信号的产生(信号源触发)
    信号由 “信号源” 触发,触发后并不会直接递送给进程,而是先由内核 “暂存”。常见的信号源及触发机制如下:
  • 用户输入:如Ctrl+C(SIGINT),由终端驱动程序检测到按键后,通过系统调用通知内核产生对应信号。
  • 进程主动发送:其他进程通过kill()、raise()等系统调用发送信号(如kill -9 ),内核会根据调用参数生成目标信号。
  • 硬件异常:如进程访问无效内存(SIGSEGV)、除以零(SIGFPE),由 CPU 检测到异常后触发 “陷阱(Trap)”,内核捕获陷阱后生成对应信号。
  • 内核主动触发:如定时器到期(SIGALRM)、管道破裂(SIGPIPE)、子进程退出(SIGCHLD),由内核在特定事件发生时主动生成信号。
  1. 信号的内核管理:“pending” 状态与进程控制块(PCB)

信号产生后,内核并不会立即 “叫醒” 进程处理,而是先将信号标记为 “待处理(pending)”,存放在进程的进程控制块(PCB,即task_struct结构体) 中。每个进程的task_struct(内核中描述进程的核心数据结构)有两个关键字段用于管理信号:

  • sigset_t pending:“待处理信号集”,用位图(bitmask)表示(每个 bit 对应一个信号,如 bit15 对应SIGTERM),bit 置 1 表示信号已产生但未被处理。
  • sigset_t blocked:“阻塞信号集”,同样是位图,bit 置 1 表示该信号被进程暂时 “屏蔽”(即使已 pending,也不会被递送,直到阻塞解除)

这意味着,若进程阻塞了SIGINT(blocked的 bit2 置 1),此时用户按下Ctrl+C,内核会将pending的 bit2 置 1,但不会立即递送给进程,直到进程解除对SIGINT的阻塞。

  1. 信号的递送:进程从 “用户态” 切换到 “内核态” 时触发
    信号不会 “主动打断” 进程的执行,而是在进程从用户态切换到内核态后,返回用户态前被内核 “检查并递送”。这是因为进程在用户态执行时,内核无法直接干预,只有当进程因系统调用、中断、异常等进入内核态后,内核才有机会处理信号。在进程准备从内核态返回用户态前,内核会检查该进程的pending信号集:
  • 若没有未处理的信号(或信号被blocked),直接返回用户态,继续执行进程原代码。
  • 若有未被阻塞的pending信号,内核会 “递送” 该信号:从pending中清除该信号(bit 置 0),然后执行信号对应的处理逻辑。

内核对信号的管理

Linux的进程控制块task_struct中,struct sighand_struct 结构体用于存储信号处理表,而struct sigaction 是 Linux 系统中用于注册和配置信号处理方式的核心数据结构,负责设定处理信号的函数和处理信号的时候需要屏蔽的信号集合。

struct sigaction {void (*sa_handler)(int);  // 处理信号的函数sigset_t sa_mask;         // 处理信号时需要屏蔽的信号集int sa_flags;             // 额外的行为控制标志
};

在进程的 task_struct 结构中,信号处理信息存储在:

struct task_struct {...struct signal_struct *signal;   // 进程共享的信号状态,用于同一个线程组内的信号共享struct sighand_struct *sighand; // 信号处理表...
};

sighand 指向 信号处理表,其中存储了 所有信号的处理方式。

Linux信号合集

Linux中的信号分为标准信号和实时信号,标准信号是 Linux 从早期 UNIX 继承的传统信号,编号为 1~31(SIGRTMIN之前,通常SIGRTMIN=34),用于处理常见的系统事件和错误。实时信号是 POSIX 标准引入的扩展信号,编号从 SIGRTMIN(通常 34)到SIGRTMAX(通常 64),用于处理需要可靠传递的事件(如实时系统中的设备通知、进程间高优先级通信)。他们最主要的区别如下:
在这里插入图片描述

每个信号都有一个唯一的编号和默认行为,进程通常用SIG前缀标识。以下是一些常见的Linux信号及其含义:

1. 常用基础信号

信号名称编号含义与典型场景默认行为
SIGTERM15终止信号:最常用的“礼貌”终止进程的信号,允许进程清理资源后退出。
例如:kill <进程ID> 默认发送此信号。
终止进程
SIGKILL9强制终止信号:无法被进程捕获、阻塞或忽略,直接用于立即
SIGINT2中断信号:用户按下 Ctrl+C 时触发,请求进程中断当前操作。终止进程
SIGQUIT3退出信号:用户按下 Ctrl+\ 时触发,与 SIGINT 类似,但会生成核心转储(core dump)用于调试。终止进程并生成core dump
SIGHUP1挂起信号:通常在终端关闭时发送给关联进程,或用于通知进程重新加载配置(如nginx、systemd)。终止进程(可被进程重定义为“重新加载”)

2. 进程状态相关信号

信号名称编号含义与典型场景默认行为
SIGSTOP19暂停信号:强制进程暂停执行(类似“冻结”),无法被忽略或捕获。暂停进程
SIGCONT18继续信号:恢复被 SIGSTOPSIGTSTP 暂停的进程。恢复进程执行
SIGTSTP20终端暂停信号:用户按下 Ctrl+Z 时触发,进程可捕获并自定义处理(如进入后台)。暂停进程

3. 错误与异常信号

信号名称编号含义与典型场景默认行为
SIGSEGV11段错误:进程访问无效内存地址(如空指针、越界访问)时触发。终止进程并生成core dump
SIGILL4非法指令:进程执行了无效的机器指令(如损坏的二进制文件、硬件不支持的指令)。终止进程并生成core dump
SIGFPE8浮点异常:数学运算错误(如除以零、浮点溢出)。终止进程并生成core dump
SIGBUS7总线错误:比 SIGSEGV 更底层的内存错误(如访问未对齐的内存地址)。终止进程并生成core dump

4. 其他常用信号

信号名称编号含义与典型场景默认行为
SIGALRM14闹钟信号:进程通过 alarm()setitimer() 设置的定时器到期时触发。终止进程
SIGPIPE13管道破裂:向已关闭的管道(或Socket)写入数据时触发(如客户端断开连接后服务器仍发送数据)。终止进程
SIGCHLD17子进程状态变化:子进程终止、暂停或继续时,内核发送给父进程,用于父进程回收子进程资源。忽略(需手动处理)
http://www.dtcms.com/a/336644.html

相关文章:

  • 【Linux】五种IO模型
  • JVM学习笔记-----StringTable
  • react 错误边界
  • Python 内置模块 collections 常用工具
  • 【撸靶笔记】第二关:GET -Error based -Intiger based
  • Spring Framework :IoC 容器的原理与实践
  • CW32L011_电机驱动器开发板试用
  • 工作中使用到的时序指标异常检测算法 TRPS 【Temporal Residual Pattern Similarity】和 K-sigma 算法
  • 区块链:数字时代信任基石的构建与创新
  • 25年第十本【金钱心理学】
  • 1. Docker的介绍和安装
  • 洛谷 P2324 [SCOI2005] 骑士精神-提高+/省选-
  • CE桥接MuMu模拟器
  • 计算机网络 Session 劫持 原理和防御措施
  • IC验证 AHB-RAM 项目(一)——项目理解
  • 【leetcode】58. 最后一个单词的长度
  • Python大模型应用开发-核心技术与项目开发
  • 【165页PPT】基于IPD的研发项目管理(附下载方式)
  • vue路由懒加载
  • 数据链路层(1)
  • Linux操作系统软件编程——多线程
  • 基于飞算JavaAI实现高端算法性能优化:从理论到落地的性能跃迁实践
  • C++---迭代器删除元素避免索引混乱
  • 【Golang】:函数和包
  • 因果语义知识图谱如何革新文本预处理
  • os详解,从上面是‘os‘模块?到核心组成和常用函数
  • 智能合约里的 “拒绝服务“ 攻击:让你的合约变成 “死机的手机“
  • 什么是AI Agent(智能体)
  • nature子刊:MCNN基于电池故障诊断的模型约束的深度学习方法
  • [Oracle数据库] Oracle 多表查询