自旋锁:对共享资源的访问保护锁,使用“自旋”方式循环查询等待获取互斥锁。
在Linux中,有多套spinlock操作接口。但是,实现机制并不相同。
根据使用场景,实现机制可能是“自旋“,也可能不是”自旋”方式。
这些实现机制的共通特点是:以不产生调度的方式,获取互斥锁。
但是,在实时Linux(RtLinux)中,spinlock却是产生调度的。
spinlock的不产生调度机制决定了用途:
1、对共享数据的访问操作时间一定要短。不同系统对实时性要求不同,这个时间要求有差异,应该控制在5us以内。
2、spinlock接口性能较高,适用在高频繁使用,但是冲突又少的场景。
3、spinlock一般作为系统基础接口,保护共享资源。例如,mutex中含有的基础变量的保护,需要使用spinlock接口。
与mutex的差异:
mutex是以可产生调度的方式保护共享资源。当一方占用资源时,另一方可挂起等待,能够释放CPU资源。
mutex在单核、多核、普通Linux,RtLinux中,都能对共享资源保护,没有差异,接口统一。
mutex只能在线程上下文中,在允许调度的环境中才能使用。
spinlock可在中断、线程、单核、多核等场景中使用。在不同的配置下,实现方式不同,不同的场景需要选择不同的接口,在Linux中使用最为广泛。Spinlock使用场景宽泛,接口数量和使用限制多,容易导致错误,一定要注意。
接口 | linux单核 | linux多核 | rt-linux |
---|---|---|---|
spin_lock | 锁抢占 | 锁抢占+自旋方式锁变量 | 互斥量 |
spin_lock_irq | 锁中断+锁抢占 | 锁中断+锁抢占+自旋方式锁变量 | 互斥量 |
spin_lock_irqsave | 锁中断+锁抢占 | 锁中断+锁抢占+自旋方式锁变量 | 互斥量 |
spin_lock_bh | 锁软中断 | 锁软中断+自旋方式锁变量 | 锁软中断+互斥量 |
raw_spin_lock | 锁抢占 | 锁抢占+自旋方式锁变量 | 同linux单核或多核 |
raw_spin_lock_irq | 锁中断+锁抢占 | 锁中断+锁抢占+自旋方式锁变量 | 同linux单核或多核 |
raw_spin_lock_irqsave | 锁中断+锁抢占 | 锁中断+锁抢占+自旋方式锁变量 | 同linux单核或多核 |
raw_spin_lock_bh | 锁软中断 | 锁软中断+自旋方式锁变量 | 同linux单核或多核 |
普通linux:
spin_lock:在线程间保持互斥保护
spin_lock_irq: 在线程间、以及线程、中断、软中断间保持互斥同步
Spin_lock_bh: 在线程间、以及线程和软中断间保持互斥同步
实时linux:
spin_lock: 在线程间保持互斥同步
spin_lock_irq:在线程间、以及线程、中断线程、软中断线程保持互斥同步
spin_lock_bh: 在线程间、以及线程和软中断线程保持互斥同步
raw_spin_lock_irq:在线程间、以及线程、中断、中断线程、软中断线程间保持互斥同步
`在spinlock的保护区内,不允许调用阻塞函数 ★★★★★``
完成量、schedule_work、wakelock、wakeup等因为接口中有spin_lock的操作,该操作在RT-LINUX上是阻塞接口,所以不能用于中断上下文。
转载于:https://blog.51cto.com/13824435/2131756