C++ memory_order_acquire/release场景下该多线程断言是否会失败?
问题1:断言是否存在触发失败的可能?
完全可能触发失败,核心原因有两点:
- 线程调度不存在时间保证:
std::this_thread::sleep_for仅能让当前读取线程阻塞指定时长,操作系统完全可能因为系统负载、调度策略等原因,让write_y对应的t3线程在t1睡眠结束、甚至整个程序运行结束前都没有被分配CPU执行,此时t1读取y时拿到的还是初始值0,断言直接触发。 - 没有同步机制保证y的写入可见性:哪怕t3已经物理层面完成了y的
relaxed写入,由于y的写入操作和t1的读取操作之间没有任何happens-before同步关系,C++标准不保证t1的relaxed读取能拿到最新值,哪怕你把睡眠时长拉得再长也没有效力。
问题2:关于acquire永远看不到y写入的说法是否正确?
这个说法不正确,你对acquire-release语义的理解存在偏差:
- acquire-release的同步覆盖范围是:针对同一个原子变量,release写入线程在写入操作之前的所有内存操作,对acquire读取到该写入值的线程的后续操作可见。你这个场景里y的写入是在独立的t3线程中,并不是t2的release写入x之前的操作,本来就不在这组同步对的覆盖范围内,和release操作前有没有其他内存操作完全无关。
- 你不是“永远看不到”y的写入,而是没有C++标准层面的保证你一定能看到。多次测试断言不失败只是因为你的测试环境(x86强内存模型、系统负载低)下大概率能读到y的新值,这属于平台和环境的偶然结果,不是语言标准的强制保证。
内容的提问来源于stack exchange,提问作者AmirCH
相关产品推荐
相关产品推荐

