1. 自旋锁1.1 概念:自旋锁是一种典型的对临界资源进行互斥访问的手段,其名称来源于它的工作方式。为了获得一个自旋锁,在某 CPU 上运行的代码需先执行一个原子操作,该操作测试并设置某个内存变量,如果测试结果表示锁已经空闲,则程序获得这个自旋锁并继续执行,如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个"测试并设置"操作。当然当锁的持有者通过重置该变量释放这个锁后,某个等待的操作向其使用者报告锁已释放。理解锁最简单的方法是把它作为一个变量看待。使用的时候需要注意一下的问题:自旋锁是忙等锁。使用时要求短平快可能导致系统死锁。如果一个已经拥有某个自旋锁的 CPU 想第二次获得这个自旋锁,该CPU 将锁死。锁定期间不能调用可能引起进程调度的函数。如果进程获得自旋锁之后再阻塞(如调用copy_from_user()、copy_to_user()、kmalloc()、msleep等函数)可能导致内核崩溃。
1. 2 函数:定义:
spinlock_t lock;
初始化:
spin_lock_init(lock);
这是一个宏,用于动态的初始化一个锁
获得锁:
spin_lock(lock);
功能:
获得自旋锁,
获得,返回
不能获得,自旋在那里
spin_trylock(lock);
尝试获得自旋锁,
能立即获得锁,获得锁返回 真
不能获得,返回 假
释放锁:
spin_unlock(lock);
自旋锁主要针对 SMP 或单 CPU 单内核支持可抢占的情况,使临界区不受别的 CPU 和本 CPU 内的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候,还可能受到中断和底半部的影响。解决办法是:
spin_lock_irq() = spin_lock() + local_irq_disable() /* 关中断加锁 */
spin_unlock_irq() = spin_unlock() + local_irq_enable()
spin_lock_irqsave() = spin_lock() + local_irq_save()
spin_lock_irqrestore() = spin_unlock() + local_irq_restore()
spin_lock_bh() = spin_lock() + local_bh_disable() /* 关底半部加锁 */
spin_unlock_bh() = spin_unlock() + local_bh_enable() |