自旋锁是一种轻量级的锁定,只能用于临界区短的代码段内,否则会降低系统运行的效率。
自旋锁主要是针对SMP(多核)或单核CPU但内核可抢占的情况,对于单CPU且内核不抢占的系统,自旋锁会退化成空操作。
自旋锁涉及的函数:
1、spin_lock_irq() = spin_lock() + local_irq_disable()
2、spin_unlock_irq() = spin_unlock() + local_irq_enable()
3、spin_lock_irqsave() = spin_lock() + local_irq_save()
4、spin_unlock_irqrestore() = spin_unlock() + local_irq_restore()
5、spin_lock_bh() = spin_lock() + local_bh_disable()
6、spin_unlock_bh() = spin_unlock() + local_bh_enable()
7、spin_lock() / spin_unlock()
其中:1-6:为适用于防止中断和底半部的影响;7:适用于仅防止进程间的抢占调度影响
注意:
1、在多核编程的时候,如果进程和中断可能访问同一个临界资源,一般在进程上下文中调用spin_lock_irqsave()/spin_unlock_irqrestore()【可以保存和恢复之前CPU的中断状态】;在中断上下文中调用spin_lock()/spin_unlock()【因为在多核CPU中,中断可以在多个核心中看作是进程,所以spin_lock相当于禁止了别的核进程的调用】.
2、spin_lock_irqsave()/spin_unlock_irqrestore()和spin_lock_irq()/spin_unlock_irq()的区别主要在于是否保存中断状态,spin_lock_irq()/spin_unlock_irq()默认中断状态为全开。
3、在自旋锁锁定期间不能调用如下可能引起进程调度的函数:copy_from_user()、copy_to_user、kmalloc()和msleep()等。