在中断程序内 变量的加加,这种情况是否会出现BUG!

2019-12-27 19:02发布

先说明一下   a=a+1这条程序语句的执行步骤:
javascript:;

我在想这种情况:
如果执行到第一步,将a的值读到寄存器R中

执行完这一条后,来了个中断就是 a=a-1 !
等执行完 a=a-1 ,这时候重点来了!

我的CPU会回到 a=a+1 的第二步!
R寄存器里面是不知道 a 已经被改变了,所以他还是按照原先的值 加1!
然后在写回到 a !
  
这时候就会出现bug了!
这种情况大伙们有考虑过吗?  要怎么避免?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
84条回答
jm2011
1楼-- · 2020-01-02 00:33
在中断里面肯定不敢用互斥锁的,推荐自旋锁;

但是个人也不推荐在中断里面加锁,我一般都是在中断里面发EVENT,另外再单开线程等待,两个线程之间保护;

楼上,MIPS的LL/SC指令就是原子的,ARM和SPARC估计也有;8051和AVR不清楚哈
823032003
2楼-- · 2020-01-02 00:47
本帖最后由 823032003 于 2016-12-3 21:29 编辑
helislayer 发表于 2016-12-3 19:44
我比较孤陋寡闻,你举例一下什么单片机的指令可以缺省状态保证原子修改?
我知道的,AVR, 8051,MIPS,  ...



我记错了,是除去load store外,中间add 那一个操作是单指令完成。。。。。。。
helislayer
3楼-- · 2020-01-02 02:29
jm2011 发表于 2016-12-3 21:02
在中断里面肯定不敢用互斥锁的,推荐自旋锁;

但是个人也不推荐在中断里面加锁,我一般都是在中断里面发EV ...

中断里面不能用带 spin 版本的 spinlock 的。只能 trylock。
如果中断里面 spin 的话,被中断的如果拿了 lock 就歇菜了。

而且中断里面用 spinlock 又拿不到 lock 就很麻烦,要
推迟处理这些。

MIPS 的 LL 那个和 ARM 的 LdrEx 是一个原理,
都不是一个指令来作 Load-Modify-Writeback, 前面说的
单个指令原子Load-Modify-Writeback 不是一回事 。
lxl_lxl
4楼-- · 2020-01-02 05:32
这点有点像脏数据,底层上面都说了那么多就不重复了,也没必要,寄存器保护原子处理了神马的,楼主好像是要最后显示的脏数据问题。

应用层上面,看任务需求,能够在最后一步检查该数据是否有效。
例如
函数入口,检测值为真,读取最新值。
函数运行,期间中断
函数末尾,验证检测值,是否重新计算,或者丢包形式。[数据非要展示那只能楼上提到的关中断处理,真多看程序的设计问题。]
要是非要说最后一步显示数据的时候来中断..只能说...这谁设计的需求,到底是要什么数据。。,加上原子时钟好了比赛数据谁先到。。

参考数据库的脏数据问题,例如银行的存取款,多线程读写,互斥锁,跟楼主提的问题都相似。
helislayer
5楼-- · 2020-01-02 07:38
 精彩回答 2  元偷偷看……
jm2011
6楼-- · 2020-01-02 09:25
helislayer 发表于 2016-12-3 22:03
中断里面不能用带 spin 版本的 spinlock 的。只能 trylock。
如果中断里面 spin 的话,被中断的如果拿了  ...

同意啊,所以说不要在中断里面来处理数据,中断就是发出事件,通知有数据来了;

具体的响应和数据处理在其他的地方做,这个应该是标准做法

一周热门 更多>