linux并发控制之自旋锁
自旋锁是一种对临界资源进行互斥访问的典型手段,其名来源于它的工作方式。
通俗的讲,自旋锁就是一个变量,该变量把一个临界区标记为“我当前在运行,请等待”或者标记为“我当前不在运行,可以被使用”, 如果A执行单元首先获得锁,那么当B进入同一个例程时将获知自旋锁已被持有,需等待A释放后才能进入,所以B只好原地打转(自旋)。
特点:
1.自旋锁主要针对SMP或单CPU且内核可抢占的情况,对于单CPU且内核不可抢占的系统自旋锁退化为空操作
2.尽管自旋锁可以保证临界区不受别的CPU和本CPU的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候还可能受到中断和底半部影响,此时应该使用 自旋锁的衍生操作
注意:
1.自旋锁实际上是等于忙等待锁,所以要求占用锁的时间极短
2.对于同一CPU或进程,不可递归使用自旋锁
3.自旋锁锁定期间不能调用可能引起进程调度的函数,比如,copy_from_user(),copy_to_user(), kmalloc(),msleep()
操作
定义于#include<linux/spinlock_types.h>
spinlock_t lock; //定义自旋锁
spin_lock_init(&lock); //初始化自旋锁
spin_lock(&lock); //如不能获得锁,原地打转。
spin_trylock(&lock); //尝试获得,如能获得锁返回真,不能获得返回假,不在原地打转。
spin_unlock(&lock); //与spin_lock()和spin_trylock()配对使用。
自旋锁衍生操作 = 自旋锁+ 中断屏蔽
spin_lock_irq()
spin_unlock_irq()
spin_lock_irqsave()
spin_unlock_irqrestore()
spin_lock_bh()
spin_unlock_bh()
用法:
spinlock_t lock; //定义自旋锁 --全局变量
spin_lock_init(&lock); //初始化自旋锁 --初始化函数中
spin_lock(&lock); // 获取自旋锁 --成对在操作前后使用
...临界区...
spin_unlock(&lock) //释放自旋锁