You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ std::atomic在ISR与主循环共享变量场景下的使用疑问

问题解答

1. 原子类型在ISR上下文的运作逻辑

C++标准定义的原子类型核心保证是操作的不可分割性,这个特性和执行上下文无关,不需要原子机制感知当前是在ISR还是普通线程/主循环:

  • 对于对齐的整型变量(你示例中的int属于这类),主流架构下原子的读、写、读改写操作都会被编译器映射为单CPU指令,而CPU响应中断的时机是指令执行间隙,所以单指令操作不管在主循环还是ISR中执行,都不可能被中断打断,天然满足原子性要求。
  • 部分架构下复杂的原子操作可能会用到总线锁机制,这种机制的有效性也不依赖执行上下文,即使在ISR中执行也能保证操作不被其他总线主设备(比如DMA、其他核心)打断,不会出现操作半完成的状态。
  • ISR不可被中断的特性不仅不会影响原子操作的正确性,反而会进一步降低冲突概率:主循环的原子操作只会被ISR打断,而ISR的原子操作不会被主循环打断,两者的操作始终是串行执行的,不会出现并行冲突。

2. 操作有效性保证

你要求的两个特性都可以得到保证:

  • 只要ISR被正常触发,x++作为原子操作一定会完整执行,不会出现执行到一半被切走的情况,x的值要么完全不更新,要么完全更新为自增后的值,不存在中间态。
  • 主循环中y = x的原子读操作,一定会读到x的完整有效值:要么是ISR执行x++前的旧值,要么是x++执行完成后的新值,不会读到部分位更新的脏值,完全符合你的要求。

额外优化建议

如果是嵌入式裸机场景,你可以显式指定宽松内存序进一步降低开销,对这个场景功能没有影响:

#include <atomic>
std::atomic<int> x;

void isr() {
    // 仅保证自增操作原子性,不需要额外内存同步
    x.fetch_add(1, std::memory_order_relaxed);
}

void loop() {
    // 仅保证读取操作原子性,不需要额外内存同步
    int y = x.load(std::memory_order_relaxed);
}

只要你使用的工具链的C++标准库适配当前硬件平台,以上实现就和你之前用汇编封装的atomic_get效果完全一致,不需要额外做中断屏蔽之类的操作。


内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 04:51:03