关闭

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

761人阅读 评论(0) 收藏 举报

设计了一个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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:45920次
    • 积分:1063
    • 等级:
    • 排名:千里之外
    • 原创:57篇
    • 转载:2篇
    • 译文:1篇
    • 评论:7条
    文章分类
    最新评论