一个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--之前先关闭中断,等完成后重新打开中断。





阅读更多
上一篇iso9660重新回顾
下一篇iOS编程遇到的一些难点问题总结
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭