Linux信号的保存

Linux系统中信号的保存涉及内核为每个进程维护的数据结构,确保信号在产生后、处理前被正确记录和管理。以下是详细的解释:

1. 信号的基本概念

  • 信号(Signal) :用于通知进程发生了特定事件的异步通知机制,如SIGINT(Ctrl+C终止进程)、SIGTERM(终止请求)等。
  • 信号处理方式:进程可为每个信号指定处理方式------默认(如终止)、忽略或自定义处理函数。

2. 信号的保存结构

  • 待处理信号集(Pending Signals) :记录已产生但尚未递送给进程的信号。由内核通过以下结构管理:
    • 标准信号(1-31):使用位掩码(每个信号对应一个位)记录是否发生。多次触发同一信号时,仅记录一次(不排队)。
    • 实时信号(34-64):使用队列保存,确保多次触发时每个信号实例均被记录。
  • 阻塞信号集(Blocked Signals):通过信号掩码(Signal Mask)标记被阻塞的信号。阻塞的信号会停留在待处理集中,直到解除阻塞。

3. 关键数据结构

  • 进程描述符(task_struct :内核为每个进程维护的结构,包含:
    • struct sigpending pending:待处理信号集合。
      • sigset_t signal:标准信号的位掩码。
      • struct list_head list:实时信号的队列。
    • sigset_t blocked:阻塞信号掩码。
    • struct sigaction sigaction[NSIG]:信号处理函数表。

4. 信号递送流程

  1. 信号产生 :通过kill()、终端输入或硬件异常等方式触发。
  2. 内核检查阻塞状态
    • 若信号未被阻塞,立即递送(调用处理函数或执行默认操作)。
    • 若被阻塞,信号被添加到pending集合(标准信号置位,实时信号入队)。
  3. 解除阻塞时处理
    • 当进程调用sigprocmask()解除阻塞或从系统调用返回时,内核检查pending集合,递送未阻塞的信号。
  4. 处理顺序
    • 标准信号 :按信号编号从小到大处理。
    • 实时信号:按发送顺序处理(队列先进先出)。

5. 信号处理期间的阻塞

  • 默认情况下,进程执行信号处理函数时,自动阻塞当前信号,防止递归调用。
  • 可通过sigaction()sa_mask字段指定额外阻塞的信号,确保处理函数原子性。

6. 示例场景

  • 场景1 :进程阻塞SIGINT(Ctrl+C):
    • 用户多次按下Ctrl+C,SIGINT被标记在pending中(仅一次)。
    • 解除阻塞后,进程处理一次SIGINT
  • 场景2 :发送实时信号SIGRTMIN多次:
    • 每次发送均入队,解除阻塞后按顺序处理所有实例。

7. 注意事项

  • 信号丢失:标准信号不排队,频繁触发可能导致丢失。
  • 可重入性 :信号处理函数应使用异步安全函数(如write()),避免死锁或数据损坏。
  • 系统调用中断 :信号可能中断阻塞的系统调用(如read()),需检查EINTR错误并重试。

总结

Linux通过pending集合和blocked掩码管理信号保存,标准信号与实时信号分别采用位图和队列实现不同语义。理解这些机制有助于编写健壮的信号处理代码,避免竞态条件和信号丢失。

相关推荐
唯创知音11 分钟前
WT2605A录音方案实现高保真音频采集本地存储云端同步!
网络·音视频·录音芯片·录音方案·录音上传
阿巴阿巴boer13 分钟前
用wsl搭建远程linux服务器
linux·运维·服务器·ssh
@CLoudbays_Martin1116 分钟前
什么是IP黑洞?
网络·网络协议·tcp/ip
qqssss121dfd20 分钟前
计算机网络(第8版,谢希仁)第三章习题解答
网络·计算机网络·php
starvapour1 小时前
Ubuntu硬盘的创建分区、格式化与挂载
linux·ubuntu
lisanmengmeng1 小时前
docker 方式安装部署禅道zentao(五)
运维·docker·容器
小立爱学习1 小时前
ARM64 指令 --- CASP / CASPA / CASPL / CASPAL
linux·c语言
知识分享小能手1 小时前
CentOS Stream 9入门学习教程,从入门到精通,CentOS Stream 9 中 Linux C 编程 —语法详解与实战案例(13)
linux·学习·centos
wanhengidc2 小时前
云手机的硬件依赖性如何?
运维·服务器·智能手机·云计算
piaoroumi2 小时前
UVC调试
linux·运维·前端