Fork Me on GitHub

源码开放学ARM

LASO - Learn ARM with Source Open

首页         目录索引         资料下载         代码下载         联系作者        
下载PDF打印版本

自旋锁

自旋锁的定义

自旋锁是一种对临界资源进行互斥访问的典型手段,其名来源于它的工作方式, 通俗的讲,自旋锁就是一个变量,该变量把一个临界区标记为“我当前在运行,请等待”或者标记为“我当前不在运行,可以被使用”, 如果A执行单元首先获得锁,那么当B进入同一个例程时将获知自旋锁已被持有,需等待A释放后才能进入,所以B只好原地打转(自旋)。

自旋锁的特点

1、自旋锁主要针对SMP或单CPU且内核可 抢占的情况,对于单CPU且内核不可抢占的系统自旋锁退化为空操作。

2、在单CPU且内核可抢占的系统中,自旋锁持有期间内核的抢占被禁止。

3、尽管自旋锁可以保证临界区不受别的 CPU和本CPU内的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候还可 能受到中断和底半部影响,此时应该使用 自旋锁的衍生操作。

自旋锁使用的注意事项

1、自旋锁实际上是忙等待锁,当锁不可用时,CPU一直循环的执行“测试并设置”该锁,直到可用而取得该锁,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。 因此只有占用锁的时间极短的情况下使用自旋锁才是合理的。如果临界区很大并且有共享的设备时使用自旋锁会降低系统的性能。

2、自旋锁有可能导致死锁。

A、同一CPU或进程递归使用自旋锁。

B、获得自旋锁后发生阻塞,一般引起阻塞的函数有 copy_from_user(),copy_to_user(), kmalloc()等,所以在自旋锁的占用期间内不能调用这些函数。

自旋锁的操作函数

定义在 linux/spinlock_types.h

1、定义自旋锁
spinlock_t lock;

2、初始化自旋锁
spin_lock_init(&lock);

3、获得自旋锁
spin_lock(&lock);
如不能获得,原地打转。
spin_trylock(&lock);
尝试获得,如能获得返回真,不能获得返回假,不在原地打转。	

4、释放自旋锁
spin_unlock(&lock);
与spin_lock()和spin_trylock()配对使用。

5、自旋锁衍生操作
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)

自旋锁的衍生(略)

1、读写自旋锁

读写自旋锁(rwlock)是一种比自旋锁粒度更小的自旋锁机制,它保留了“自旋”的概念,但是在写操作方面,只能最多有一个写进程,在读方面,同时可拥有多个执行单元,当然读和写也不能同时进行。

2、顺序锁

顺序锁(seqlock)是对读写锁的一种优化,若使用顺序锁,读执行单元不会被写执行单元阻塞,写执行单元也不需要等待所有的读执行单元完成读操作才去进行写操作。 但写执行单元和写执行单元之间是互斥的。如果在读执行单元读的过程中写执行单元发生了操作,那么读执行单元必须重新读取数据,以确保得到的数据是完整的。

上一节 | 目录索引 | 下一节

blog comments powered by Disqus