在多任务环境中。如果任务具有表达式 y = x + x;
x 的两次读取之间是否有可能发生中断(任务切换)。
最佳答案
在大多数情况下,编译器生成的代码只会读取 x 一次,因为优化是微不足道的。事实上,它甚至可能将操作转换为右移,相当于 x << 1
。但是你不能保证这一点,如果 x
被宣布volatile
它必然会进行两次读取,然后在低位和高位字的读取之间不间断(反之亦然),在这种情况下 y
的分配也是可中断的。
另一个问题是,如果 x
不是原子数据类型(即无法在单个指令中读取),例如 16 位目标上的 32 位类型,那么即使它是单个读取,它也可能是可中断的。
无论哪种情况,如果x
通常都是一个问题。本身(或在第二种情况下 y
)在上下文之间共享(在这种情况下,它也应该声明 volatile
因此需要两次读取),或者如果由于某种原因分配的时间在某种程度上至关重要并且需要完全确定性(不太可能)。
如果x
是共享的,因此 volatile
但是是原子类型,此示例中的简单解决方案是编写表达式 y = x << 1
或y = x * 2
确保x
只读一次。哪里x
不是原子的 - 您可能需要锁定调度程序或禁用中断(即使用关键部分),或者例如使用互斥体更有选择性地保护访问。对于无法将表达式简化为对共享变量的单个引用的更复杂的表达式,只需将变量分配给非共享局部临时变量即可确保仅读取该变量一次。原子性问题仍然存在。
关于c - 识别干扰的可能性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38394047/