自旋锁
自旋锁最多只能被一个内核任务持有。要是锁未被持有,请求它的内核任务便会立即得到它并继续执行。如果一个内核任务试图请求一个已经被别的内核任务持有的自旋锁,那么CPU就会一直尽心循环---旋转---等待锁重新可用。
Spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
或者在运行时使用:
Void spin_lock_init(spinlock_t *lock);
得到自旋锁:
Void spin_lock(spinlock *lock);
释放自旋锁:
Void spin_unlock(spinlock_t *lock);
尽管自旋锁可以保证临界区不受别的执行单元的抢占打扰,但是得到锁的代码在执行临界区的时候还是可能受到本地中断的影响,为了防止这种影响,要需要用到自旋锁的衍生函数:
(1) void spin_lock_irqsave(spinlock_t *lock, unsigned long falgs);
获得自旋锁之前禁止本地中断,之前的中断状态保存在flags里。
释放函数:void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
(2) void spin_lock_irq(spinlock_t *lock);
获得自旋锁之前禁止本地CPU中断,但不保存中断状态。
释放函数:void spin_unlock_irq(spinlock_t *lock);
(3) void spin_lock_bh(spinlock_t *lock);
获得自旋锁之前禁止软中断,允许硬件中断。
释放函数:void spin_unlock_bh(spinlock_t *lock);
自旋锁使用注意:
(1)不可以长期加锁,只能短期加锁;
(2)会有系统开销(CPU忙转),不能滥用;
(3)在持有自旋锁的同时,不能持有信号量;
(4)在持有自旋锁的同时,不能再二次持有它(死锁);