自旋锁spin_lock

来源:互联网 发布:网络弹棉花是什么意思 编辑:程序博客网 时间:2024/05/22 10:53
 

1.大部分加锁是由一种称为自旋锁的机制来实现, 自旋锁可用在不能睡眠的代码

中, 例如中断处理一个自旋锁是一个互斥设备, 只能有 2 个值:"上锁"和"解锁".

它常常实现为一个整数值中的一个单个位. 想获取一个特殊锁的代码测试相关的

位. 如果锁是可用的, 这个"上锁"位被置位并且代码继续进入临界区. 相反, 如

果这个锁已经被别人获得, 代码进入一个紧凑的循环中反复检查这个锁,直到它变

为可用. 这个循环就是自旋锁的"自旋"部分.
2.自旋锁原语要求的包含文件是 <linux/spinlock.h>. 一个实际的锁有类型
spinlock_t
-------------------------------------------------------------
自旋锁相关的操作
1.定义自旋锁
spinlock_t lock;
2.初始化自旋锁
spin_lock_init(lock);该宏用于动态初始化自旋锁lock
3.在进入一个临界区前, 你的代码必须获得需要的 lock
spin_lock(lock);如果能够立即获得锁,它就马上返回,否则,它将自旋在那里

,直到该自旋锁的保持都释放。注意所有的自旋锁等待是, 由于它们的特性, 不

可中断的. 一旦你调用spin_lock, 你将自旋直到锁变为可用.
spin_trylock(lock);该宏尝试获得自旋锁lock,如果能立即获得,他获得锁并返

回真,否则立即返回假,实际上不再在原地打转
4.释放一个你已获得的锁
spin_unlock(lock);
------------------------------------------------------------
1.应用到自旋锁的核心规则是任何代码必须, 在持有自旋锁时, 是原子性的. 它

不能睡眠; 事实上, 它不能因为任何原因放弃处理器, 除了服务中断(并且有时即

便此时也不行)
2.自旋锁一般这样被使用
spinlock_t lock;
spin_lock_init(&lock);
spin_lock(&lock);/*获得自旋锁,保护临界区*/
/*临界区*/
spin_unlock(&lock);
3.自旋锁主要针对SMP或单CPU但内核可抢占的情况,对于单CPU内核不支持抢占的

系统,自旋锁退化为空操作。
4.自旋锁可以保证临界区不受别的CPU或本CPU内的抢占进程打扰,但是得到锁的

代码路径在执行临界区的时候,还可能受到中断和底半部的影响。
自旋锁 API 的完整理解需要对中断处理和相关概念的理解.
实际上有 4 个函数可以加锁一个自旋锁
void spin_lock(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
void spin_lock_irq(spinlock_t *lock);
void spin_lock_bh(spinlock_t *lock
也有 4 个方法来释放一个自旋锁; 你用的那个必须对应你用来获取锁的函数.
void spin_unlock(spinlock_t *lock);
void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
void spin_unlock_irq(spinlock_t *lock);
void spin_unlock_bh(spinlock_t *lock);
5.使用自旋锁要注意如下几个问题
1)自旋锁实际上是忙等锁,当锁不可通知时,CPU一直循环执行“测试并设置”该锁直到可用而取得该锁,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。因此只有在占用锁的时间极短的情况下,使用自旋锁才合理。
2)自旋锁可能导致系统死锁。(递归使用自旋锁)
3)自旋锁锁定期间不能调用可能引起进程调度的函数。