多线程间的获取-释放内存顺序

Acquire-release memory order between multiple threads

代码:

std::atomic<int> done = 0;
int a = 10;

void f1() {
  a = 20;
  done.store(1, std::memory_order_release);
}

void f2() {
  if(done.load(std::memory_order_acquired) == 1) {
    assert(a == 20);
  }
}

void f3() {
  if(done.load(std::memory_order_acquired) == 1) {
    assert(a == 20);
  }
}

int main() {
  std::thread t1(f1);
  std::thread t2(f2);
  std::thread t3(f3);
  t1.join();
  t2.join();
  t3.join();
}

问题是如果线程 2 和 3 都看到 done == 1,将 断言 a == 20 在两个线程中都成立? 我知道 acquire-release 适用于一对线程。但是确实 它也适用于多线程吗?

是的。释放-获取关系分别适用于 all 对线程(访问相同的原子位置!)并保证 all 写入(出现在程序顺序)在发布之前对 所有 读取(出现在程序顺序中)在相应的获取之后可见。

发布就像出版一份报纸(没有明确的周期),获取就像现在购买下一版,然后发现它说的是什么(不关心它是哪个版本,或者它是哪一天) . (您很少需要对这些共享原子进行版本控制,尽管有时可能需要。)

任何数量的人都可以购买报纸。重要的是印刷时印刷的内容是真实的,并且如果它们是不变的真理,则仍然是真实的,例如纪念碑的创建(假设不变)。

因此,发布操作会发布发布时的真实情况,适当的设计可确保在您可以 "buy"(获取)发布时这些事实不会发生变化。任何数量的线程都可以看到这些事实。