竟态-自旋锁spinlock

自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

信号量对互斥来讲是非常有用的工具,但它并不是内核提供的唯一的这类工具。相反,大多数锁定通过称为“自旋锁”的机制实现。和信号量不同,自旋锁可在不能休眠的代码中使用,比如中断处理例程。在正确使用的情况下,自旋锁通常可以提供比信号量更高的性能。

自旋锁原语所需要包含的文件是<linux/spinlock.h>。实际的锁具有spinlock_t类型。和其他任何数据结构类似,一个自旋锁必须被初始化。

编译时初始化:

spinlock_t my_lock = SPIN_LOCK_UNLOCKED;

运行时初始化:

void spin_lock_init(spinlock_t *lock);

获取锁:

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

void spin_lock_irq(spinlock_t *lock);

void spin_lock_bh(spinlock_t *lock);

spin_lock_irqsave会在获得自旋锁之前禁止中断(只在本地处理器上),而先前的中断状态保存在flags中。

如果我们能确保没有任何其他代码禁止本地处理器的中断(或者换句话说,我们能够确保在释放自旋锁时应该启用中断),则可以使用spin_lock_irq,而无需保存标志。

spin_lock_bh在获得锁之前禁止软件中断,但是会让硬件中断保持打开。这里bn是bottom half的缩写,也就是中断的底半部(软件中断),和它对应的中断的顶半部(硬件中断)。

如果我们有一个自旋锁,它可以被运行在(硬件或软件)中断上下文中的代码获得,则必须使用某个禁止中断的spin_lock形式,因为使用其他的锁定函数迟早会导致系统死锁。如果我们不会在硬件中断处理例程中访问自旋锁,但可能在软件中断访问,则应该使用spin_lock_bh,以便在安全地避免死锁的同时还能服务硬件中断。

释放锁:

void spin_unlock(spinlock_t *lock);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);

void spin_unlock_irq(spinlock_t *lock);

void spin_unlock_bn(spinlock_t *lock);

 

还有两个非阻塞的版本:

void spin_trylock(spinlock *lock);

void spin_trylock_bh(spinlock *lock);

 

很重要的一点,任何拥有自旋锁的代码都必须是原子的。它不能休眠,事实上,它不能因为任何原因放弃处理器,除了服务中断以外(某些情况下此时也不能放弃处理器)。

许多操作会使程序进入休眠,例如copy_from_user、kmalloc等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值