正确使用自旋锁、互斥锁

最近在看alios-things的代码发现驱动程序中大量使用了自旋锁 。
如tty.c里面的函数实现都是通过自旋锁来实现对资源的访问保护。
在这里插入图片描述
看到这里首先会有疑问,自旋锁能保护临界区吗?
一般来说,自旋锁是用于多核系统的不同核心之间对同一个数据区的竞争访问,对于同一个核上的不同线程是不具备防护功能的。(网上有文章解析自旋锁是让线程原地等待,并没有突出smp环境下的核间竞争,这是不对的,自旋锁就是永远多核处理器之间的资源防护,而不是多线程的资源防护)

怀着上述疑问,打开aos_spinlock.c看一下相关接口底层实现,发现这些spinlock操作实际上是复合了关中断的操作的。
所以,看到这里,这些接口应该命名为aos_irqlock_xxx更为合适。不然在单核情况下,这里的自旋锁就仅保存了锁中断功能,名字和功能就对不上了。

另外,继续深入的想一想,驱动中大量使用关中断是否合适呢?
在大量io存在的情况下,这种关中断可能要降低系统性能,这时候互斥锁应该是更好的选择。
互斥锁在lock、unlock时会有短暂的关中断,在锁持有过程中是不需要关闭中断的。这样也就可以在大量io的过程给中断以及其他线程运行的机会,可以在io过程更充分的利用处理器资源。

网上也有讨论不关中断,独立使用自旋锁的,如果确信自己在干什么,当然也没问题,如果是设计一套通用的接口提供给其他用户使用,并不能确定用户的使用场景,还是老老实实关中断使用吧。

上网搜了一下自旋锁,发现不少错误描述,很多将自旋锁和互斥锁做对比的,解析的也比较雷同,都是一些在阅读代码过程中产生的一些感性认识,缺乏理论依据。

下面是我对自旋锁的总结,如果有疑问或者不对的地方请留言指正,感谢!

首先,自旋锁是为解决多核系统的资源竞争而设计的,需要处理器的原子操作来实现。其次,自旋锁是其他内核保护机制的底层基础,如信号量、互斥锁等在多核系统里是要依赖自旋锁来实现其功能。

单核情况下,只要关闭中断,系统就相当是独占的,但是在多核情况下,关闭中断,只能保证当前处理器不被抢夺,而不能保证其他处理器核上的线程来竞争资源 。

多核情况下,处理器提供了特殊指令实现对单元数据的原子访问,可以允许每个核心来对该单元数据的状态进行原子的设置操作,如果有多核同时进行这一设置操作,则只有一个会成功,其他的返回失败,失败的可以重复这一过程,直到成功,这就是自旋锁的实现原理。
根据上述描述可知,自旋锁的持有时间要尽可能的短,否则,可能导致其他处理器被长时间自旋挂起。传统的互斥量、信号量等内核元素就是获得自旋锁后快速对自身变量完成设置后归还自旋锁(设置自旋锁为空闲状态)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值