概念
spinlock
又称自旋锁
,是为实现保护共享资源而提出的一种轻量级锁机制。
原理
自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个持有者,即只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,而是一直循环在那里看是否该自旋锁的持有者已经释放了锁,"自旋"一词就是因此而得名。锁一旦被释放,就会被等待的线程立即获取,而不需要经过唤醒和上下文切换。
有个经典的例子来比喻自旋锁:甲乙两个人合租一套房子,共用一个厕所,那么这个厕所就是共享资源,且在任一时刻最多只能有一个人在使用。当厕所闲置时,谁来了都可以使用。当甲使用时,就会关上厕所门,而乙也要使用,但是急啊,就得在门外焦急地等待,急得团团转,是为“自旋”。
特性
- 用于临界区互斥保护。
- 在任何时刻最多只能有一个执行单元获得锁。
- 要求持有锁的处理器所占用的时间尽可能短。
- 等待锁的线程进入忙循环,而不是休眠等待。
- 不需要进行上下文切换和任务调度。
- 消耗过多CPU资源:如果申请不成功,申请者将一直循环判断,这无疑降低了CPU的使用率。
- 可能会死锁:申请者试图递归地获得自旋锁必然会引发死锁。
- 只对SMP(同构多核)系统有效,对于单核CPU,同一时刻只能运行一个线程或中断,CPU必定是要让出的,所以不可能有一个“自旋”运行着的线程来等待另一个已获取资源的运行线程。
- 为了统一接口,单核系统上也有自旋锁,但其实现本质是空操作或者是关中断操作。
适用情况
自旋锁是一种比较低级的资源保护方式比较适用于保护访问耗时较短
的资源。信号量和互斥锁适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在线程上下文使用;而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。如果被保护的共享资源只在线程上下文访问,可以使用信号量保护该共享资源,如果对共享资源的访问时间非常短,自旋锁则更合适。但是如果被保护的共享资源需要在中断上下文访问就必须使用自旋锁。自旋锁保持期间是抢占失效的,而信号量和互斥锁保持期间是可以被抢占的。