1. 信号机制的本质:软中断与进程通信
Linux信号机制本质上是一种异步通信的软中断实现。与硬件中断不同,信号完全由软件实现,但采用了类似中断的处理机制——当信号到达时,当前执行流程会被暂停,转而执行信号处理函数。这种设计使得进程能够及时响应外部事件,而不必主动轮询状态变化。
信号在进程控制块(PCB)中通过位图进行管理。每个进程维护两个关键数据结构:
- 未决信号集(pending):记录已到达但尚未处理的信号
- 阻塞信号集(blocked):决定哪些信号会被暂时屏蔽
当内核检测到信号事件时,会在目标进程的pending集合中设置对应位。在进程从内核态返回用户态前,会检查pending集合,对未阻塞的信号依次进行处理。这种延迟处理的机制确保了信号处理不会打断关键的内核操作。
关键细节:信号处理函数执行时,系统会自动将该信号加入阻塞集,防止递归调用。处理完成后才会解除阻塞,这解释了为什么同一个信号的快速连续发送不会导致处理函数重入。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 信号的分类与标准信号详解
2.1 可靠信号 vs 不可靠信号
Linux将信号划分为两大类别:
- 不可靠信号(1-31):早期UNIX信号,存在以下缺陷:
- 不支持排队,相同信号多次发送可能丢失
- 信号处理函数每次调用后需重新注册
- 执行期间自动阻塞该信号
- 可靠信号(34-64):POSIX标准新增信号,改进特性包括:
- 支持信号排队,确保不丢失
- 处理函数永久有效
- 可通过附加信息传递数据
2.2 关键标准信号解析
以下是在实际开发中最常遇到的信号及其典型应用场景:
| 信号编号 | 名称 | 触发场景 | 默认动作 |
|---|---|---|---|
| 1 | SIGHUP | 终端断开/控制进程终止 | 终止 |
| 2 | SIGINT | Ctrl+C触发 | 终止 |
