当前位置: 首页 > article >正文

Linux 自旋锁

当内核发生访问资源冲突的时候,可以有两种锁解决方案:

1.原地等待

2.挂起当前进程,调度其它进程执行

spinklock 是内核中提供的一种比较常见的锁机制,自旋锁是“原地等待” 的方式解决资源冲突的,即,一个线城获取看一个自旋锁后,另外一个线程期望获取该自旋锁,获取不到,只能够原地“打转” (忙等待)。

由于自旋锁的这个忙等待的特性,注定了它的使用场景的限制-------自旋锁不应该被长时间的持有(消耗CPU资源),一般应用在中断上下文。

什么情况用什么锁

获得自旋锁和释放自旋锁有好几个版本,因此让读者知道在什么样的情况下使用什么版本的获得和释放
锁的宏是非常必要的。
如果被保护的共享资源只在进程上下文访问和软中断上下文访问,那么当在进程上下文访问共享资源
时,可能被软中断打断,从而可能进入软中断上下文来对被保护的共享资源访问,因此对于这种情况,
对共享资源的访问必须使用spin_lock_bh和spin_unlock_bh来保护。当然使用spin_lock_irq和
spin_unlock_irq以及spin_lock_irqsave和spin_unlock_irqrestore也可以,它们失效了本地硬中断,失
效硬中断隐式地也失效了软中断。但是使用spin_lock_bh和spin_unlock_bh是最恰当的,它比其他两个
快。
如果被保护的共享资源只在进程上下文和tasklet或timer上下文访问,那么应该使用与上面情况相同的获
得和释放锁的宏,因为tasklet和timer是用软中断实现的。
如果被保护的共享资源只在一个tasklet或timer上下文访问,那么不需要任何自旋锁保护,因为同一个
tasklet或timer只能在一个CPU上运行,即使是在SMP环境下也是如此。实际上tasklet在调用
tasklet_schedule标记其需要被调度时已经把该tasklet绑定到当前CPU,因此同一个tasklet决不可能同
时在其他CPU上运行。timer也是在其被使用add_timer添加到timer队列中时已经被帮定到当前CPU,
所以同一个timer绝不可能运行在其他CPU上。当然同一个tasklet有两个实例同时运行在同一个CPU就更
不可能了。
如果被保护的共享资源只在两个或多个tasklet或timer上下文访问,那么对共享资源的访问仅需要用
spin_lock和spin_unlock来保护,不必使用_bh版本,因为当tasklet或timer运行时,不可能有其他
tasklet或timer在当前CPU上运行。如果被保护的共享资源只在一个软中断(tasklet和timer除外)上下
文访问,那么这个共享资源需要用spin_lock和spin_unlock来保护,因为同样的软中断可以同时在不同
的CPU上运行。
如果被保护的共享资源在两个或多个软中断上下文访问,那么这个共享资源当然更需要用spin_lock和
spin_unlock来保护,不同的软中断能够同时在不同的CPU上运行。
如果被保护的共享资源在软中断(包括tasklet和timer)或进程上下文和硬中断上下文访问,那么在软中
断或进程上下文访问期间,可能被硬中断打断,从而进入硬中断上下文对共享资源进行访问,因此,在
进程或软中断上下文需要使用spin_lock_irq和spin_unlock_irq来保护对共享资源的访问。而在中断处理
句柄中使用什么版本,需依情况而定,如果只有一个中断处理句柄访问该共享资源,那么在中断处理句
柄中仅需要spin_lock和spin_unlock来保护对共享资源的访问就可以了。因为在执行中断处理句柄期
间,不可能被同一CPU上的软中断或进程打断。但是如果有不同的中断处理句柄访问该共享资源,那么
需要在中断处理句柄中使用spin_lock_irq和spin_unlock_irq来保护对共享资源的访问。
在使用spin_lock_irq和spin_unlock_irq的情况下,完全可以用spin_lock_irqsave和
spin_unlock_irqrestore取代,那具体应该使用哪一个也需要依情况而定,如果可以确信在对共享资源访
问前中断是使能的,那么使用spin_lock_irq更好一些,因为它比spin_lock_irqsave要快一些,但是如果
你不能确定是否中断使能,那么使用spin_lock_irqsave和spin_unlock_irqrestore更好,因为它将恢复
访问共享资源前的中断标志而不是直接使能中断。当然,有些情况下需要在访问共享资源时必须中断失
效,而访问完后必须中断使能,这样的情形使用spin_lock_irq和spin_unlock_irq最好。


http://www.kler.cn/news/314563.html

相关文章:

  • Spring Mybatis 动态语句 总结
  • 简单生活的快乐
  • (k8s)kubernetes集群基于Containerd部署
  • Flask-SQLAlchemy一对多 一对一 多对多关联
  • GDPU Andriod移动应用 Activity
  • 【数据结构与算法】LeetCode:哈希表
  • Alinx MPSoC驱动开发第17章I2C实验修改设备树后petalinux编译报错
  • 分布式Id生成策略-美团Leaf
  • 使用python对图像批量水平变换和垂直变换
  • 深度学习参数管理
  • MySQL-DDL/DML(数据定义/操作语言)
  • GIS开发之如何使用OpenLayers,Leaflet,Mapbox,Cesium,ArcGIS, Turf.js 与 D3.js
  • 【Webpack--00802】配置Babel语法兼容
  • 【图像检索】基于Gabor特征的图像检索,matlab实现
  • Python面试宝典第50题:分割等和子集
  • Vscode、插件历史版本下载
  • [数据结构与算法·C++] 笔记 1.4 算法复杂性分析
  • [附源码]SpringBoot+VUE+Java实现人脸识别系统
  • 实战指南:深度剖析Servlet+JSP+JDBC技术栈下的用户CRUD操作
  • 探秘 Web Bluetooth API:连接蓝牙设备的新利器
  • 828华为云征文|Flexus X实例GitLab部署构建流水线-私人一体化代码仓库~
  • AWS账号可以共用吗?
  • vue 中互相不关联的两个组件怎么进行通信(数据传输)
  • MFC获取网页的html文本
  • 视频V4改进
  • 锐捷 睿易路由器存在RCE漏洞
  • 会声会影2025视频剪辑教学
  • 开源集成开发环境搭建之VSCode安装部署教程
  • MySQL:基本查询操作
  • java计算机毕设课设—土地档案管理系统(附源码、文章、相关截图、部署视频)