自旋锁
自旋锁
自旋锁概念
锁有自旋与睡眠两种。当进程无法获取锁资源,该进程不会休眠,会一直循环等待,一直到资源可用。
自旋锁接口函数
接口函数定义在include\linux\spinlock.h中,接口函数:
函数名 |
作用 |
spin_lock_init(_lock) |
初始化自旋锁为unlock状态 |
void spin_lock(spinlock_t *lock) |
获取自旋锁(加锁),返回后肯定获得了锁 |
int spin_trylock(spinlock_t *lock) |
尝试获得自旋锁,成功获得锁则返回1,否则返回0 |
void spin_unlock(spinlock_t *lock) |
释放自旋锁,或称解锁 |
int spin_is_locked(spinlock_t *lock) |
返回自旋锁的状态,已加锁返回1,否则返回0 |
自旋锁实现
自旋,自己等待资源可用,原地旋转。一旦资源可用,就锁上自旋锁,标志资源占用,其它不能抢占。
引入问题:如果此时资源不可用,原地“旋转”是要消耗CPU资源。这样别的程序怎么运行?别的程序不执行完,有怎么解锁,释放资源?
对于多个内核,原地旋转在CPU0上,在CPU1上执行其它程序,完成解锁,释放资源。
对于单CPU资源,自旋锁的“自旋”功能去掉,保有的功能是禁止抢占,禁止中断。这样可以尽快解锁,释放资源。
在执行期间,不要引入休眠或者阻塞,因为自旋锁关闭了抢占与中断。如果,进入阻塞或者休眠,会很容易引起死锁。
在单核 自旋实现
对于“自旋锁”,它的本意是:如果还没获得锁,就原地打转等待(不休眠)。等待谁释放锁? 在单核中,只有其它线程/进程
如果在单内核中,不支持抢占。那么在执行的线程不可能被其它线程抢占,这样上锁函数就是空操作。
单内核系统支持抢占。在执行过称中,正在执行的线程可能被其它线程抢占。而自旋锁的作用就是让正在执行的线程尽快执行,解锁,释放资源。
这样自旋锁的作用就是禁止抢占,禁止中断。由于其它线程在等待访问其它资源,等到获取旋锁,其并没有进入休眠状态,而是在运行,等待资源释放。
由此,自旋锁不适用那些操作时间较长的场景。