【并发与竞争】spin自旋锁

spin自旋锁

自旋锁不管是内核编程,还是应用层编程都会用到;自旋锁和互斥量类似,它不是通过休眠使进程阻塞,而是在获取锁之前一直处于忙等(也就叫自旋)状态。互斥锁和自旋锁,他们俩是最底层的锁,很多高级的锁都是基于他们去实现的。

spin是互斥锁,即只有上锁和解锁两个状态值。它一般被描述为一个数的单个位。如果自旋锁可用,那么该单个位将会被被置位并且代码进入临界区,相反,如果这个锁已经被他人获得,代码便进入一个紧凑的循环中反复检查这个锁,直到锁可用。此时这个循环就是自旋锁的“自旋”部分。

在上所说的“置位”必须是原子操作,就算如果有多个进程在任何给定时间自旋,那也只有一个线程能够获得锁。必须小心以避免在超线程处理器上死锁–实现多个虚拟 CPU 以共享一个单个处理器核心和缓存的芯片. 因此实际的自旋锁实现在每个 Linux 支持的体系上都不同. 核心的概念在所有系统上相同, 然而, 当有对自旋锁的竞争, 等待的处理器在一个紧凑循环中执行并且不作有用的工作.

它们的特性上, 自旋锁是打算用在多处理器系统上, 尽管一个运行一个抢占式内核的单处理器工作站的行为如同 SMP(也就是所谓的多处理器), 如果只考虑到并发. 如果一个非抢占的单处理器系统进入一个锁上的自旋, 它将永远自旋; 没有其他的线程再能够获得 CPU 来释放这个锁. 因此,自旋锁在没有打开抢占的单处理器系统上的操作被优化为什么不作, 除了改变IRQ屏蔽状态的那些. 由于抢占, 甚至如果你从不希望你的代码在一个 SMP 系统上运行, 你仍然需要实现正确的加锁.

所以总结的来说

  • 自旋锁与互斥锁的使用框架以及场景都是相似的
  • 互斥锁得不到锁会休眠,而自旋锁是进入到一个紧凑的循环里忙等并检测锁的状态
  • 使用场景自旋锁比较适合保护变量赋值、函数调用等
  • 自旋锁的机制是用来在多核环境中,由于共享内存,存在对同一资源访问的情况,需要互斥访问机制只有一个核进行操作。
  • 当自旋锁变为可用时,CPU不能做其他任何事情,这是自旋锁只能够只能持有一小段时间的原因之一。
  • 自旋锁必须初始化:
#include <linux/spinlock.h>
spinlock_t lock = SPIN_LOCK_UNLOCKED;
//或直接调用函数:
void spin_lock_init(spinlock_t *lock);

加锁和解锁

void spin_lock(spinlock_t *lock);
void spin_unlock(spinlock_t *lock);

在使用自旋锁时要注意几个点:

  • 在持有一个锁时避免睡眠
  • 自旋锁必须一直是尽可能短的持有时间,过长的时间会对整个系统整体有明显影响
  • Need to have interrupts disabled when locked by ordinary threads, if shared by an interrupt handler。
禁止中断的自旋锁spin_lock_irqsave

函数声明:

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
/*
lock:被定义且初始化过的锁;
flags:保存本地中断状态;
*/

函数功能:

  • 保存本地中断状态

  • 关闭本地中断

  • 获取自旋锁

spin_loc_irqsave 禁止中断(只在本地处理器)在获得自旋锁之前,之前的中断状态保存在flags里。且在调用spin_unlock_irqsave()时,需注意flag的变量必须是和上锁时是同一个变量。

其中对第二个参数flag是否需要初始化,网上是这么说的:

spin_lock_irqsave()中的flags初始化

spin_lock_irqsave里会对其进行初始化。如果不对flag的值初始化,编译器可能会报警告,为了避免这些警告,最好进行初始化。

spin_lock_irq
void spin_lock_irq(spinlock_t *lock)

spin_lock_irqsave的区别:

如果确保在处理器中没有禁止中断的,即确定在释放自旋锁时有打开中断,则可以用spin_lock_irq代替,并且不必保持跟踪flags。

void spin_lock_bh(spinlock_t *lock)

最后,spin_lock_bh在获取锁之前禁止软件中断, 但是硬件中断留作打开的。

网上对于一系列锁的总结

面试官:你说说互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景

问题:

不论是哪一篇文章对锁的论述时,都提到了会不会放弃CPU这个概念,所以放弃CPU这个是什么样的一个操作?

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Van.Ghylivan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值