自旋锁 死锁

以前在看linux操作系统时始终理解不了单CPU 自旋锁 导致 死锁 的问题.今天在网上搜了一下总算是理解了.摘录如下

想象你的内核代码请求到一个 自旋锁 并且在它的临界区里做它的事情,在中间某处,你的代码失去了处理器。或许它已调用了一个函数(copy_from_user,假设)使进程进入睡眠。也或许,内核抢占发威,一个更高优先级的进程将你的代码推到了一边(注意,这都是假设, 自旋锁 其实不允许这些操作)。此时,正好某个别的线程想获取同一个锁,如果这个线程运行在和你的内核代码不同的处理器上(幸运的情况),那么它可能要自旋等待一段时间(可能很长),当你的代码从休眠中唤醒或者重新得到处理器并释放锁,它就能得到锁。而最坏的情况是,那个想获取锁得线程刚好和你的代码运行在同一个处理器上,这时它将一直持有CPU进行自旋操作,而你的代码是永远不可能有任何机会来获得CPU释放这个锁了,这就是悲催的 死锁 。 

自旋锁 有几个重要的特性:1、被 自旋锁 保护的临界区代码执行时不能进入休眠。2、被 自旋锁 保护的临界区代码执行时是不能被被其他中断中断。3、被 自旋锁 保护的临界区代码执行时,内核不能被抢占。从这几个特性可以归纳出一个共性:被 自旋锁 保护的临界区代码执行时,它不能因为任何原因放弃处理器。 


注:所以现代处理器在处理 自旋锁 时都会设定自旋上限时间以防 死锁
自旋锁 在单核非抢占式CPU上是无效的.被设为空操作,不做任何事. 


可能你会奇怪,持有 自旋锁 的进程在执行内核代码时是不能被抢占的,那么为什么在可抢占式系统中有用呢.其实linux在设计可抢占式系统的 自旋锁 时只是把 自旋锁 设计为"只是禁止内核抢占",而没有自旋(所以使用 自旋锁 的代码一定要可以很快执行完,否则进程就一直持着锁不释放,也不可被抢占).可是理解为只是实现了一个不被打扰的原子操作,操作完后释放锁.所以它不能休眠. 
linux上的 自旋锁 有三种实现: 
1. 在单cpu,不可抢占内核中, 自旋锁 为空操作。 
2. 在单cpu,可抢占内核中, 自旋锁 实现为“禁止内核抢占”,并不实现“自旋”。(注意) 
3. 在多cpu,可抢占内核中, 自旋锁 实现为“禁止内核抢占” + “自旋”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值