由于关键代码区可以跨越了多个函数或数据结构,需要有更通用的同步方法:锁。
内核中最常见的一种锁就是自旋锁。相同的锁可用于多处。
自旋锁可用在不可睡眠的场景,如中断处理函数。自旋锁是一种互斥设备,只有两个值:“锁定”和“非锁定”。它通常实现为一个整数值的某个比特位。想获取某个锁的代码首先测试相关的位,如果锁可得,则该位的“锁定”位被置位,代码继续执行,反之,代码将进入一个紧凑的循环,不停地检测锁定位直至自旋锁变得可得。该循环是自旋锁的“旋转”部分。自旋锁主要用于多处理器的情况下。
1.通用自旋锁
相关操作:
DEFINE_SPINLOCK(mr_lock)
spinlock_tmy_lock = SPIN_LOCK_UNLOCKED;//静态初始化
或
voidspin_lock_init(spinlock_t *lock);//动态初始化
获取自旋锁
voidspin_lock(spinlock_t *lock);//不可中断的
释放自旋锁
voidspin_unlock(spinlock_t *lock);
使用自旋锁时要禁止中断,禁止睡眠,并且应当尽可能减少占用自旋锁的时间。
其他函数
voidspin_lock(spinlock_t *lock);
//在获取自旋锁之前,禁止中断
voidspin_lock_irqsave(spinlock_t *lock, unsigned long flags);
voidspin_lock_irq(spinlock_t *lock);
//禁止软件中断,但允许硬件中断
voidspin_lock_bh(spinlock_t *lock)
对应的解锁函数如下:
voidspin_unlock(spinlock_t *lock);
voidspin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
voidspin_unlock_irq(spinlock_t *lock);
voidspin_unlock_bh(spinlock_t *lock);
非阻塞自旋锁操作(成功返回非0,允许中断)
intspin_trylock(spinlock_t *lock);
intspin_trylock_bh(spinlock_t *lock);