多线程间的获取-释放内存顺序
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"(获取)发布时这些事实不会发生变化。任何数量的线程都可以看到这些事实。