本文不对自旋锁和互斥锁的概念做阐述,重点分析它们之间的区别和自旋锁的使用场景。

自旋锁和互斥锁的区别

a. 互斥锁加锁失败后,线程会释放 CPU,给其他线程;自旋锁加锁失败后,线程会忙等待,直到它拿到锁;
b. 自旋锁会关闭本CPU内核抢占,互斥锁不会.
问:为什么自旋锁要关闭本CPU内核抢占?
答:加锁进程A获取一把自旋锁之后,开始执行临界区代码,此时发生了调度,执行进程B。恰巧进程B需要用到该自旋锁,这就导致了死锁的发生.

自旋锁和互斥锁的使用场景

a. 如果我们明确知道被锁住的代码的执行时间很短,那我们应该选择开销比较小的自旋锁
b. 如果临界区需要睡眠,应该选择互斥锁
c. 中断里应该使用自旋锁,因为中断处理中不允许睡眠

自旋锁在中断场景使用需要注意的点

a. spin_lock_irq的使用
问1:中断的到来,一定会打断正在执行的 CPU 的进程,哪怕是当前的程序被 spin_lock 给锁住了,假设当前的中断也需要访问该 spin_lock 锁,那么就会导致死锁发生。
解决:所以应该在进程执行临界区代码段的自旋锁上锁之前,首先就应该关闭当前 CPU 的中断,这样无论你发生什么情况,一旦被锁上就不再会被任何的情况抢走 CPU,这就是 spin_lock_irq 出现的原因.
缺点:由于需要关闭当前CPU中断,会导致系统的响应降低,性能下降.

b. spin_lock_irqsave的使用
问2:自旋锁嵌套使用

死锁原因:当进程在执行第一个 spin_lock_irq(&lock1) 时已经关闭了中断,然后继续获取第二个自旋锁 spin_lock_irq(&lock2),当 lock2 解锁后且 lock1 未解锁前这一段区域处于一种硬件中断开启的状态,
这段代码仍然处于 lock1 的临界区,如果此时硬件中断也需要申请 lock1 锁会导致死锁,这是因为 spin_unlock_irq 在解锁时一定会将本地 CPU 的中断打开,从而导致硬件中断可以重新强制抢占 CPU.
解决:所以最好的方式就是 lock2 在锁之前保存当前的中断状态,在解锁时恢复当前的中断状态,这也就是 spin_lock_irqsave 需要存在的原因。自然地,这是一种更为线程安全的方案,但是他会带来比前面几种更加多的性能损耗。

总结

spin_lock 使用场景

首先如果整个临界区都只位于进程上下文或者工作队列中,那么只需要采用最为方便的 spin_lock 即可,因为他不会发生中断抢占锁的情况,哪怕中断抢占进程上下文也不会导致中断由于申请自旋锁而导致死锁。还有一种情况就是在硬件中断中可以考虑使用 spin_lock 即可,因为硬件中断不存在嵌套(未必一定是这样,与平台有关),所以只需要简单的上锁即可, 可以不需要关闭中断,保存堆栈等。

spin_lock_irq 使用场景

这个锁的变种适合在进程上下文/软中断 + 硬件中断这样的组合中使用,taskset 也是属于软中断的一种,所以也归在此类。当然,这种类型的变种同样适合软中断/taskset + 进程上下文的组合,因为关闭了硬件中断,从源头就禁止执行软中断代码,不过,对于这种类型的中断最好的方式是使用 spin_lock_bh 的方式,因为他只锁定软中断代码执行,而不关闭硬件中断,这样性能损耗更小。

spin_lock_irqsave 使用场景

这种类型的使用方式是最为安全以及便捷的,毕竟不需要考虑会不会发生死锁的问题(代码本身引入的死锁不在此类),但是他也是性能损耗最大的代码,能不使用尽量不适用,在高速设备上,自旋锁已然成为了一种降低性能的瓶颈。他最好只出现在在需要尝试 spin_lock 之前无法确定是否已经关闭中断的代码才使用,如果代码能够确定在执行锁之前中断一定是打开的,那么使用 spin_lock_irq 是更佳的选择。

spin_lock_bh 使用场景

这种类型的变种是一种比 spin_lock_irq 更轻量的变种,只关闭中断底半部,其实就是关闭了软中断、Taskset 以及 Timer 等的一个抢占能力,如果开发者确定编写的代码临界区只存在软中断/Taskset/Timer + 进程上下文这样的组合,则最好考虑使用 spin_lock_bh 这样的锁来禁止软中断进行抢占。还有就是软中断与软中断自我抢占临界区访问时,也需要使用 spin_lock_bh 以上的中断锁,因为有可能软中断在执行的过程中,自己被硬件中断打断,然后又执行到同样的代码,在别的 CPU 执行还好说,毕竟软中断可以在不同的 CPU 上执行同一个中断函数,但是假设不幸运行在同一个 CPU 上,则会导致死锁。Taskset 由于在运行过程中钟只会运行一个实例,所以不存在死锁问题,Taskset 与 Taskset 的锁竞争只需要使用 spin_lock 即可。

自旋锁与互斥锁的使用场景分析相关推荐

  1. 关抢占 自旋锁_互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景

    前言 生活中用到的锁,用途都比较简单粗暴,上锁基本是为了防止外人进来.电动车被偷等等. 但生活中也不是没有 BUG 的,比如加锁的电动车在「广西 - 窃·格瓦拉」面前,锁就是形同虚设,只要他愿意,他就 ...

  2. 自旋锁替代互斥锁使用场景

    自旋锁与互斥锁 自旋锁与互斥锁 理论分析 互斥锁的问题 自旋锁应用场景 自旋锁实践 总结 自旋锁与互斥锁 自旋锁和互斥锁是多线程程序中的重要概念. 它们被用来锁住一些共享资源, 以防止并发访问这些共享 ...

  3. 并发编程中常见的锁机制:乐观锁、悲观锁、CAS、自旋锁、互斥锁、读写锁

    文章目录 乐观锁 VS 悲观锁 悲观锁 乐观锁 CAS CAS机制 ABA问题 CAS的优缺点 互斥锁 VS 自旋锁 互斥锁 自旋锁 对比及应用场景 读写锁 实现方式 读写锁 VS 互斥锁 乐观锁 V ...

  4. 自旋锁、互斥锁和信号量

    自旋锁 Linux内核中最常见的锁是自旋锁(spin lock).自旋锁最多只能被一个可执行线程持有.如果一个执行线程试图获得一个已经被持有的自旋锁,那么该线程就会一直进行忙循环--旋转--等待锁重新 ...

  5. C# lock 语法糖实现原理--《.NET Core 底层入门》之自旋锁,互斥锁,混合锁,读写锁...

    在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...

  6. 正确使用自旋锁、互斥锁

    最近在看alios-things的代码发现驱动程序中大量使用了自旋锁 . 如tty.c里面的函数实现都是通过自旋锁来实现对资源的访问保护. 看到这里首先会有疑问,自旋锁能保护临界区吗? 一般来说,自旋 ...

  7. c语言用户态锁使用,用户态自旋锁、读写自旋锁及互斥锁

    1.自旋锁 自旋锁最多可能被一个可执行线程所持有.一个被征用的自旋锁使得请求它的线程在等待锁重新可用时自旋(特别浪费处理器时间).所以自旋锁不应该被长时间持有. 自旋锁是不可递归的! (1)自旋锁相关 ...

  8. 分布式锁:互斥锁、自旋锁、读写锁、悲观锁、乐观锁

    前言 如何用好锁,也是程序员的基本素养之一了. 高并发的场景下,如果选对了合适的锁,则会大大提高系统的性能,否则性能会降低. 所以,知道各种锁的开销,以及应用场景是很有必要的. 接下来,就谈一谈常见的 ...

  9. 【Linux kernel】自旋锁和互斥锁

    内核当发生访问资源冲突的时候,可以有两种锁的解决方案选择: 一个是原地等待 一个是挂起当前进程,调度其他进程执行(睡眠) Linux内核提供了自旋锁和互斥锁的机制,两者都能保证在同一时刻只有一个执行单 ...

最新文章

  1. ROW_NUMBER() OVER 函数的用法
  2. 电力“十三五”蓝图发布 新能源迎发展机遇
  3. 2009年广东省大学生程序设计竞赛 J
  4. scalikejdbc 学习笔记(2)
  5. mod php是什么意思,mod函数是什么意思
  6. pycharm 右方提示 PEP 8: do not use bare 'exept'(不要只用一个except)、Too broad exeption clause(过于宽泛的例外条款)
  7. AOP的MethodBeforeAdvice
  8. fastJson toJSONString注意点
  9. redis中zset底层实现原理
  10. 2.替换空格JAVA
  11. mysql 时间戳截断_列的Mysql时间戳数据被截断
  12. VMware Horizon环境中的防病毒注意事项
  13. Rainyday.js – 傻眼了!竟然有如此逼真的雨滴效果
  14. Linuxmint 19双显卡切换的巨坑
  15. elementui messagebox没有取消按钮
  16. 制作在线单词测试的软件,Test Your Vocabulary:号称是最准的英语词汇量测试网站...
  17. 使用Xcode的Instruments检测解决iOS内存泄露(leak)
  18. TIPOP 出货单单头
  19. 管程法----生产者和消费者
  20. 许奔创新社-第18问:静默头脑风暴怎么玩?

热门文章

  1. P问题、NP问题、NPC问题、NP难问题的概念
  2. 在php中焦点事件,Js中的onblur和onfocus事件(图文教程)
  3. 期货开户的时间和流程
  4. ESP8266图形播放器 + 天气时钟显示项目更新
  5. 原生JS灵魂之问——你真的懂这些JS吗?
  6. remote-cloudflare-kv 在 Vercel 上使用 Cloudflare KV
  7. 自学大学计算机专业好,大学计算机专业学自我鉴定(通用5篇)
  8. Python:简单的TCP网络编程
  9. GUI编程(Python版)
  10. 安装pycharm专业版