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

C++原子操作acquire/release语义与RMW操作同步问题:单次acquire加载能否与多次release类型RMW操作同步?

C++原子操作acquire/release语义与RMW操作同步问题:单次acquire加载能否与多次release类型RMW操作同步?

嘿,咱们先拆解这个经典的依赖同步场景:线程A、B、C各自独立执行任务,互相不需要同步,但线程D必须等这三个线程全干完,才能合并它们的结果——说白了就是D的执行完全依赖A、B、C的完成状态。

先看给出的基础代码:

int a = 0;
int b = 0;
int c = 0;
std::atomic_int D_dependencies{ 3 };

三个工作线程的代码分别是:
线程A:

a = 1;
D_dependencies.fetch_sub(1, std::memory_order_release);

线程B:

b = 1;
D_dependencies.fetch_sub(1, std::memory_order_release);

线程C(按场景逻辑补充完整):

c = 1;
D_dependencies.fetch_sub(1, std::memory_order_release);

现在核心问题来了:如果线程D用单次acquire语义的load操作来判断D_dependencies是否为0,能不能同时和A、B、C各自的release语义fetch_sub操作建立同步关系?

答案是肯定的,完全没问题。这里得理清几个关键点:

  • 首先,fetch_sub是读-修改-写(RMW)原子操作,当指定std::memory_order_release时,这个操作的释放语义会确保:该线程中所有在fetch_sub之前的写操作(比如A里的a=1),都会被“发布”出去,对后续执行acquire语义操作的线程可见。
  • 线程D的load(std::memory_order_acquire)操作,一旦读取到0,就意味着A、B、C的三次fetch_sub都已经执行完成。这时候,D的acquire加载会和每一次的release语义fetch_sub都建立同步关系——因为原子变量的修改是原子有序的,三次fetch_sub依次把值从3降到0,D读到0的那一刻,必然已经“看到”了所有三次修改的结果。

换句话说,当D成功读到0时,它可以安全地访问a、b、c,因为A、B、C各自在fetch_sub之前的写操作,都已经通过release-acquire的同步关系,确保对D可见了。

举个线程D的示例代码:

// 循环等待所有依赖完成
while (D_dependencies.load(std::memory_order_acquire) != 0) {
    // 实际场景中可以加std::this_thread::yield()减少空循环占用,但这里重点演示原子同步
}
// 此时a、b、c的值都是1,可安全读取合并
int combined_result = a + b + c;

备注:内容来源于stack exchange,提问作者rad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:13:06