Administrator
Published on 2026-01-13 / 0 Visits
0
0

信号

信号的作用

实现inter process communication 的一种方式

区分 信号量(Semaphore) 实现锁

POSIX信号

信号名是信号序号的宏 即 #DEFINE SIGNIT 2 名字会被变成数字

https://man7.org/linux/man-pages/man7/signal.7.html

信号的发送与保存

2个N bits 的位向量, 代表N种信号

1. pending 待处理信号

2. blocked (signal mask) 屏蔽的信号

如果收到信号,就把pending对应位设置为1,重复收到同一信号后续信号没有影响

一般通过kill 函数发送信号

int kill(pid_t pid, int sig)

kill (2666, 1) ,向pid 为2666的进程发送信号1

用户进程可以互相发送信号, 内核进程可以给用户进程发送信号

但进程之间允许发送的信号是有限制的,父进程可以向子进程发送停止信号,其他进程不可以

信号的处理

处理时机

当进程从内核态转换到用户态 比如syscall返回 IO中断返回,如果有待处理信号,就处理信号

为什么这么设计

pending 和 blocked 都在PCB中,即处于内核中。我们每次检查都是完成某一次切换到内核态要完成的任务后,顺手检查信号。好处显而易见:提高效率

Q: 如果一直在用户态,那么就没法处理信号了?

理论上,如果一个进程真的能永远不出错、不调用系统接口且不被外部硬件打断,它确实无法处理信号。

但实际上这不可能,首先就是external interruption 中的时间片切换。

处理方法

result = pending & ~blocked

result 第i位为1, 那么就运行信号类型i对应的信号处理程序

信号处理程序在用户态

信号处理程序可以是操作系统的默认程序,也可以由这个进程设置自己的信号处理程序。eg. 窗口大小变化调整UI

当需要处理多个信号时,按序号从小到大依次处理

一旦处理,把对应pending位设置为1

Q: 如何重写信号处理程序的平衡灵活性和安全性

操作系统并不是允许进程重写“所有”信号的处理程序。 比如信号9 19,进程无法捕获,也无法忽略,实际上信号会发给操作系统,操作系统直接关闭。

信号与异常的关系

信号可以作为异常的配套机制

当操作系统处理一个异常,有的异常可以由操作系统独立解决(缺页异常),有的异常还需要应用程序配合(/0异常, 告诉应用程序,应用程序可以通过自己的GUI告诉用户错了;默认的处理会闪退崩溃)


Comment