首页 > 代码库 > 关于signal, kill, mutex, spinlock的一些总结

关于signal, kill, mutex, spinlock的一些总结

用户进程,在用户态可以被直接 kill 。
用户进程陷入内核,在内核态进入死循环:
1. 循环体中有 msleep_interruptible ,进程状态为S,即可中断的睡眠状态,kill 命令不能杀死进程。
2. 循环体中有 msleep ,进程状态为D,即不可中断的睡眠状态,kill 命令不能杀死进程。
3. 循环体中无 sleep ,进程状态为R,即可执行状态,kill 命令不能杀死进程。
以上三种情况,不能被kill是因为进程处于内核态,信号不会被处理,在进程退出内核态时,信号将会被处理。

内核线程默认不处理信号,也就是说不能被杀死。
如果需要内核线程处理信号,需要显示指定,加入如下代码:
allow_signal(SIGXXXX);
并且在线程中处理该信号。
如果内核现在指定接收 SIGKILL 信号,并且受到该信号后即退出,则该内核线程可被杀死。

spinlock:
lock时首先禁止了cpu抢占,即当前进程拿到spinlock后,是不允许别的进程把它所占用的cpu抢走的,所以spinlock可以用在中断处理函数中。
当然,拿到spinlock后,当前进程也不允许schedule出去的,例如不允许调用sleep函数。如果有将自己schedule出去的操作,将会报以下bug:
BUG: scheduling while atomic:
spinlock被占用之后,除非释放,否则一直处于被占用状态。就算占用spinlock的进程被kill掉了,spinlock仍然为被占用状态。

mutex:
持有mutex的过程中,可能会被schedule出去,所以中断处理函数中不允许使用mutex。
既然可能会被schedule出去,当然也允许自己schedule出去,因此在持有mutex过程中允许sleep发生。
mutex被占用之后,除非释放,否则一直处于被占用状态。就算占用mutex的进程被kill掉了,mutex仍然为被占用状态,这一点与spinlock相同。

用户进程陷入内核,在内核态取得 mutex ,在未释放的情况下退出,其他进程再尝试获取同一 mutex 时会卡住,状态为D,即不可中断的睡眠状态。
用户进程陷入内核,在内核态取得 spinlock ,在未释放的情况下就回到用户态,执行时 kernel 将会崩溃,并打印如下信息:
BUG: scheduling while atomic:
用户进程陷入内核,在内核态取得 spinlock ,返回用户态之前释放 spinlock 是允许的。
用户进程陷入内核,在内核态取得 spinlock ,在未释放的情况下返回用户态不被允许,并且处于内核态时,进程不会被杀死,所以不存在用户进程持有 spinlock 并且被杀死的情况。

内核线程获取 mutex ,在未释放的情况下退出,其他进程再尝试获取同一 mutex 时会卡住,状态为D,即不可中断的睡眠状态。
内核线程获取 spinlock ,在未释放的情况下退出,其他进程再尝试获取同一 spinlock 时会卡住,状态为R。
获取 mutex 时,如果获取不到会进入睡眠;获取 spinlock 时,如果获取不到不会睡眠,而是忙等待。

关于signal, kill, mutex, spinlock的一些总结