一个i++的教训,多线程问题

设计了一个ring buffer,一个中断进程负责往里面写入数据,一个后台进程负责读取数据。

数据每次写入就对cnt++,每次读取就cnt--,运行一段时间之后,发现写指针和读指针对不上了,中间隔开了一段距离。

查了很久,发现很有可能是这个cnt++出了问题,因为++操作不是原子操作,需要先mov出来,++,然后写回,这样的话有可能在中断里++之后又被原先被中断的--操作覆盖。

详细的过程分析:

1. CPU执行到cnt--,

2. cnt的值(架设==5)被mov到寄存器进行--操作

3. 寄存器完成操作得到结果4

4. 把寄存器的结果写回变量的内存地址,最终得到4.

假如在第2步之后发生了中断,那么情况是:

1. CPU执行到cnt--,

2. cnt的值(架设==5)被mov到寄存器进行--操作

3. 发生中断,中断程序把临时变量入栈,保护现场,也就是把寄存器里cnt=5保存起来

4. 中断里面获取cnt的值,也是5,放入寄存器进行++运算

5. 把运算结果6写回变量的内存地址,此时内存里的值为6

6. 中断程序退出之前恢复现场,把之前的变量出栈,寄存器恢复为5并进行--运算

7. 寄存器完成操作得到结果4

8. 把寄存器的结果写回变量的内存地址,最终得到4.

这样,最终的结果就好比根本没用执行cnt++,实际上只执行了cnt--。


解决的办法:

暂时我想到的是,在需要做cnt--之前先关闭中断,等完成后重新打开中断。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值