自旋锁(Spin Lock)
自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断等部分
(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,即在标志寄存器中关闭/打开中断标志位,不需要自旋锁)。
自旋锁的性质
自旋锁最多只能被一个可执行线程所执有。
如果一个执行线程试图获得一个已经被持有的自旋锁,那么该线程会一直进行“忙循环——旋转——等待锁重新可用”的活动。即获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。这也是自旋锁中“自旋”二字的由来。
但是由于自旋锁一直使线程处于忙状态,会特别浪费处理器时间,因此不建议自旋锁被长期持有(快速操作、快速释放)。
自旋锁的使用
基本使用形式如下:
DEFINE_SPINLOCK(my_lock);
spin_lock(&my_lock);
/*临界区*/
spin_unlock(&my_lock);
注意:自旋锁一般只用在多处理器机器上,在单处理器机器上一般在编译阶段就把自旋锁优化掉了
自旋锁在使用中不允许递归,即在持有该锁的情况下再次请求该锁,显而易见,持有锁情况下等待锁的释放,这样会使两个行为互相锁死,从而使整个线程死锁。
自旋锁可以使用在中断处理程序中
在中断处理程序中使用自旋锁时,必须禁止本处理器上的中断,因为新的高优先级处理器中断可能会打断当前中断,一旦新中断打乱出现在当前中断的持锁过程,并且在新中断中也申请这个锁时,将会导致当前中断无法释放锁且新中断无法获得锁的双重请求死锁状态。
具体可以这样使用:
DEFINE_SPINLOCK(my_lock);
unsigned long flags;
spin_lock_irqsave(&my_lock,flags);/*保存中断状态并且禁止中断*/
/*临界区*/
spin_lock_irqrestore(&my_lock,flags);/*恢复并回写中断状态*/
具体的自旋锁底层实现和一些其它用法
见https://blog.csdn.net/hhhanpan/article/details/80624244