linux下竞态分析和避免

这部分内容是linux设备驱动学习总结-keyPoints中的子集,独立出来方便查找。


1、linux产生竞态主要三种情况:中断、抢占、多处理器。

一个cpu运行在进程上下文或者中断上下文(且这段上下文是临界区域)的时候可能

被中断打断,且这个中断要访问临界资源;

被其它进程抢占,且这个进程要访问临界资源;

或者其它的cpu也要访问临界区域。

这个时候就会发生竞态。


2、cpu运行在进程上下文的情况

避免中断产生的竞态,可以提前关闭中断,处理完成后在开启中断;

避免抢占产生的竞态,可以使用spin_lock,因为自旋锁锁住的临界区域是不可抢占的,但是要求临界区域尽量的短。另外在关闭中断的情况下抢占的竞态也不会发生,因为linux内核的进程调度也依赖中断实现;

针对多处理器产生的竞态,通常也是使用spin_lock,或者互斥锁也可以,至于什么时候使用互斥锁,什么时候使用自旋锁,参考第5条。

(另外2.6.35后,取消了中断嵌套,所以中断与中断产生的竞态可以不用担心了)


3、cpu运行在中断上下文的情况。

中断和抢占产生的竞态都不需要考虑,因为,2.6.35后,中断嵌套被取消,且中断上下文的优先级要高于进程上下文(抢占本身是进程抢占,运行在进程上下文)。

需要考虑的是多处理器产生的竞态,参考上一条,多处理器产生的竞态可以用spin_lock或者互斥锁来避免,但是中断不允许睡眠(互斥锁在拿不到锁的情况下会进入睡眠)所以必须使用spin_lock。


4、spin_lock在单处理器的情况下,自动退化为互斥锁(宋宝华说的,不理解其中原委)。而实际上,spin_lock在单处理器情况下没有任何意义。

想象一下单处理器运行在进程上下文,spin_lock锁住的区域可能产生竞态的情况只有中断,如果中断中也要访问这段临界区域,假如中断拿不到锁,那就彻底挂了(因为他会自旋,且我们只有一个cpu),如果顺利拿到锁,说实在的在单处理器中没有任何意义。


5、什么情况下用自旋锁,什么情况下用互斥锁?

首先,在临界区较小,占用cpu时间较短,或者任务的实时性要求较高的情况下使用自旋锁,可避免CPU频繁调度产生的开销。

其次,有可能引起阻塞的临界区绝对不可以使用自旋锁,阻塞意味着进程切换,切换到的进程如果也要spin_lock加锁,死锁就产生了。

最后,在中断和软中断中的临界区域,尽量使用自旋锁(这种情况也符合第一条,因为中断是实时性要求较高的任务),如果一定要用互斥锁,也要try_lock,因为中断程序不能睡眠。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值