spinlock同一时刻只能被一个内核代码路径持有,如果有另外一个内核代码路径试图获取一个已经被持有的spinlock,那么该内核代码路径需要一直自旋忙等待,直到锁持有者释放了该锁。如果该锁没有被别人持有(或争用,lock contention),那么可以立即获得该锁。spinlock锁的特性如下。
1、忙等待的锁机制。操作系统中锁的机制分为两类,一类是忙等待,另一类是睡眠等待。spinlock属于前者,当无法获取spinlock锁时会不断尝试,直到获取锁为止。
2、同一时刻只能有一个内核代码路径可以获得该锁。
3、要求spinlock锁持有者尽快完成临界区的执行任务。如果临界区执行时间过长,在锁外面忙等待的CPU比较浪费,特别是spinlock临界区里不能睡眠。
4、spinlock锁可以在中断上下文中使用。
spin_lock()函数最终调用__raw_spin_lock()函数来实现。首先关闭内核抢占,这是spinlock锁的实现关键点之一。那么为什么spinlock临界区不允许发生抢占呢?
如果spinlock临界区中允许抢占,那么如果临界区内发生中断,中断返回时会去检查抢占调度,这里有两个问题,一是抢占调度相当于持有锁的进程睡眠,违背了spinlock锁不能睡眠和快速执行完成的设计语义;二是抢占调度进程也有可能会去申请spinlock锁,那么会导致发生死锁。
值得声明的是,使用spinlock的一个重要原则:拥有spinlock锁的临界区代码必须是原子执行,不能休眠和主动调度。
网友评论