关于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 时,如果获取不到不会睡眠,而是忙等待。

时间: 2024-10-12 00:22:12

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

Linux命令kill和signal

Linux命令kill和signal kill命令用于终止指定的进程(terminate a process),是Unix/Linux下进程管理的常用命令.通常,我们在需要终止某个或某些进程时,先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程.kill命令的另外一个用途就是向指定的进程或进程组发送信号(The  command kill sends the specified signal to the specified process or

What is the difference between Kill and Kill -9 command in Unix?

w difference kill -9 pid and kill pid command - Ask Ubuntu  https://askubuntu.com/questions/791841/difference-kill-9-pid-and-kill-pid-command kill pid (which sends signal 15 (SIGTERM)) tells pid to terminate, but said program can execute some code fi

Linux signal 那些事儿(2)【转】

转自:http://blog.chinaunix.net/uid-24774106-id-4064447.html 上一篇博文,基本算是给glibc的signal函数翻了个身.现在glibc的signal基本修正了传统的UNIX的一些弊端,我们说signal并没有我们想象的那么不堪.但是signal也有不尽人意的地方.比如信号处理期间,我们期望屏蔽某些信号,而不仅仅是屏蔽自身,这时候signal就不行了.信号既然是进程间通信IPC的一种机制,我们期望获取更多的信息,而不仅仅是signo,这时候s

windows环境下封装条件wait和signal

linux 环境有提供好的pthread_cond_wait() 和 phread_signal().pthread_broadcast() windows需要自己封装,利用semophore控制线程等待和释放,先简单谈一下设计好后api该 如何使用. 假设我们封装好条件变量等待函数名字叫做wait(Mutex& mutex),Mutex是之前我们封装的 条件变量,文章最下边会给出这些文件的下载地址,在这里读者当做linux 的mutex即可.我们 封装的释放函数为signal(),广播函数为b

kill 发送消息给进程命令

功能: kill命令发送信号给进程. 格式: kill [-s signal|-p] [-q sigval] [-a] [--] pid... kill -l [signal] kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>] 参数: OPTIONS pid... Specify the list of processes that kill should signal. Each pid can be one of five things: n

信号,信号量,锁,条件变量,消息通信,共享内存,RPC (一)

在实际项目当中,经常需要把一个功能分成多个子模块实现.那么,这些子模块之间该如何关联起来呢?静态地看,模块可以看作一组完成相同功能的函数:而动态地看,模块可以是一个独立的进程.线程或者一个中断服务或者信号服务例程.根据不同的具体业务实现,它们之间可能是静态调用.动态互斥.同步.唤醒等关系.静态的调用很好实现,上层的函数调用底层的函数即可.那么,动态互斥.同步.唤醒等关系,又该如何实现呢?这就设计到我们将要讨论的信号.进程间消息通信.共享内存.线程互斥同步条件变量.RPC等手段.下面就按照Linu

Linux 同步方法剖析--内核原子,自旋锁和相互排斥锁

在学习 Linux® 的过程中,您或许接触过并发(concurrency).临界段(critical section)和锁定,可是怎样在内核中使用这些概念呢?本文讨论了 2.6 版内核中可用的锁定机制,包含原子运算符(atomic operator).自旋锁(spinlock).读/写锁(reader/writer lock)和内核信号量(kernel semaphore). 本文还探讨了每种机制最适合应用到哪些地方.以构建安全高效的内核代码. 本文讨论了 Linux 内核中可用的大量同步或锁定

Linux 同步方法剖析--内核原子,自旋锁和互斥锁

在学习 Linux® 的过程中,您也许接触过并发(concurrency).临界段(critical section)和锁定,但是如何在内核中使用这些概念呢?本文讨论了 2.6 版内核中可用的锁定机制,包括原子运算符(atomic operator).自旋锁(spinlock).读/写锁(reader/writer lock)和内核信号量(kernel semaphore). 本文还探讨了每种机制最适合应用到哪些地方,以构建安全高效的内核代码. 本文讨论了 Linux 内核中可用的大量同步或锁定

进程查看及命令使用-htop/dstat/top/ps命令

进程是linux用来表示正在运行的程序的一种抽象概念,程序内存的使用,处理器时间和I/O资源就是通过这个对象进行管理和监视的. 一个程序要先运行在用户空间,当他需要去使用硬件资源的时候,就不得不去调动内核才能取得使用权,这时候调动内核,进入内核空间,当内核处理完毕需求之后,将指令返回给用户,一个调用完成. 进程会以时间片段在CPU运行的,CPU以一根时间线被划分成无数个片段:当一个进程运行到某个阶段,需要暂时终止的时候,需要保存一个进程运行的现场,叫保存现场:执行到某片段的时候,需要中断,当再需