1. splin_lock在linux下面的实现,会禁止内核抢占,
代码如下:
static inline void __spin_lock(spinlock_t *lock)
{
preempt_disable();
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
}
2. 这里禁止抢占,是指禁止内核抢占。
所谓内核抢占是指:
内核进程在中断处理返回,
schedule调度。
等。。。 (这个还要具体分析)
3. 在splin_lock里面不能使用sleep操作。
假设任务A,拿到splin_lock之后,调用sleep了。 而sleep之后,A让出CPU,这个时候会发生任务调度。
任务B进来了,正好B也要获取splin_lock,那B一直在忙等状态,当然这个时候,B又禁止抢占的,那么B就不会让出CPU了。
B不让出CPU,A不能执行,不能释放spin_lock,
此时死锁发生。
过程如下:(来自于:
http://sabolasi.iteye.com/blog/1246067 )
导致死锁的过程:[1]为进程1,[2]为进程2,
[1] 关抢占
[1] 获得锁
[1] 睡眠调度 ...... 尽管已经关闭了抢占,[1]依然可以通过主动调用schedule(), schedule_timeout()等主动让出CPU,调度其它进程。
[2] 关抢占 ...... [1]已经关闭抢占,所以这里相当于nop操作
[2] 获得锁失败 ...... [1]已经获得了锁,并且还没有释放
[2] 反复尝试获得锁 ...... 由于关闭了抢占,已经没人能够终止这个反复尝试的操作了,所以这里出现了死锁