Apple M1芯片上无法复现C++ atomic LoadStore重排问题求助
无法在Apple M1上复现弱内存序问题的原因及修正方案
原Demo的核心问题
- 任务调度过于同步:每次循环添加任务后主线程休眠100ms,两个线程的任务大概率会被串行执行,难以触发ARM弱内存序下的指令重排。
- 非原子变量存在数据竞争:
r1、r2是普通int,主线程读取它们时,工作线程可能正在修改,结果的正确性无法保证。 - 尝试次数不足:仅100次循环,弱内存序重排是概率性事件,这么少的次数很难触发目标场景。
- 变量重置与任务执行无同步:主线程的
x.store(-1)等重置操作,和工作线程的任务执行没有同步机制,可能出现任务执行时变量还未完成重置的情况。
修正后的复现代码
使用无锁循环让两个线程持续执行目标操作,用原子变量检测是否出现r1 == r2 == 42的结果,一旦触发就立即终止程序:
#include <atomic> #include <iostream> #include <thread> std::atomic<int> x(-1); std::atomic<int> y(-2); std::atomic<bool> done(false); int r1, r2; void thread1() { while (!done.load(std::memory_order_relaxed)) { x.store(-1, std::memory_order_relaxed); y.store(-2, std::memory_order_relaxed); r1 = y.load(std::memory_order_relaxed); x.store(r1, std::memory_order_relaxed); // 检查是否触发目标结果 if (r1 == 42 && r2 == 42) { done.store(true, std::memory_order_relaxed); std::cout << "触发目标结果:r1=" << r1 << ", r2=" << r2 << std::endl; } } } void thread2() { while (!done.load(std::memory_order_relaxed)) { x.store(-1, std::memory_order_relaxed); y.store(-2, std::memory_order_relaxed); r2 = x.load(std::memory_order_relaxed); y.store(42, std::memory_order_relaxed); // 检查是否触发目标结果 if (r1 == 42 && r2 == 42) { done.store(true, std::memory_order_relaxed); std::cout << "触发目标结果:r1=" << r1 << ", r2=" << r2 << std::endl; } } } int main() { std::cout << "开始测试,等待触发弱内存序重排..." << std::endl; std::thread t1(thread1); std::thread t2(thread2); t1.join(); t2.join(); return 0; }
复现要点
- 编译时关闭编译器优化:使用
g++ -O0 -std=c++17 test.cpp -pthread编译,避免编译器优化掉可能触发重排的指令。 - 增加尝试次数:修正后的代码会持续循环直到触发结果,ARM架构下通常几秒到几分钟内就能出现目标场景。
- 避免同步机制干扰:去掉任务队列这类可能引入隐式同步的组件,让线程直接执行核心操作,最大化重排概率。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

