天天看点

自旋锁(spin lock)学习目的用途与互斥锁区别原理可能出现的问题使用场景

目录

目的

用途

与互斥锁区别

相同点

不同点

原理

可能出现的问题

死锁(骑驴找驴)

过多占用cpu资源

使用场景

目的

为了防止多处理器并发,保护共享资源。

用途

在内核中大量用于中断处理。

对于单处理器,防止中断处理中的并发可以采用关闭中断的方式(标志寄存器中的中断标志位)

与互斥锁区别

相同点

  • 为保护共享资源提出的锁机制:为了解决对某项资源的互斥使用。
  • 在任何时刻,最多只能有一个执行单元获得锁。
  • 一个执行单元要想访问被锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。

不同点

调度机制上不同:

对于互斥锁,如果资源已被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已被别的执行单元保持,调用者就一直循环等待。

原理

过程:

  1. 获取锁
  2. 访问共享资源
  3. 释放锁

如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即获取锁。

如果在获取锁时已经有持有者,那么锁操作将自旋,直到自旋锁的保持者释放了锁。

可能出现的问题

死锁(骑驴找驴)

试图递归地获得自旋锁必然会引起死锁:

递归程序的持有实例在第二个实例循环,以试图获得相同自旋锁时,不会释放此自旋锁。

在递归程序中使用自旋锁应遵守下列策略:

  1. 递归程序决不能在持有自旋锁时调用它自己
  2. 决不能在递归调用时试图获得相同的自旋锁

此外如果一个进程已经将资源锁定,那么,即使其它申请这个资源的进程不停地疯狂“自旋”,也无法获得资源,从而进入死循环。

过多占用cpu资源

如果不加限制,由于申请者一直在循环等待,因此自旋锁在锁定的时候,如果不成功,不会睡眠,会持续的尝试,单cpu的时候自旋锁会让其它process动不了. 因此,一般自旋锁实现会有一个参数限定最多持续尝试次数. 超出后, 自旋锁放弃当前time slice. 等下一次机会。

使用场景

自旋锁比较适用于锁使用者保持锁时间比较短的情况。

正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。

信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用,而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共享资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP(多处理器)的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。

总之,自旋锁是一种对多处理器相当有效的机制,而在单处理器非抢占式的系统中基本上没有作用。自旋锁在SMP系统中应用得相当普遍。

在许多SMP系统中,允许多个处理机同时执行目态程序,而一次只允许一个处理机执行操作系统代码,利用一个自旋锁可以很容易实现这种控制.一次只允许一个CPU执行核心代码并发性不够高,若期望核心程序在多CPU之间的并行执行,将核心分为若干相对独立的部分,不同的CPU可以同时进入和执行核心中的不同部分,实现时可以为每个相对独立的区域设置一个自旋锁. 

自旋锁的基本形式如下:

spin_lock(&mr_lock);

//临界区

spin_unlock(&mr_lock);

继续阅读