Uses of memory_order_relaxed

Uses of memory_order_relaxed

本文关键字:order relaxed memory of Uses      更新时间:2023-10-16

关于Stackoverflow,已经有一些问题主要是关于memory_order_relaxed的用例,例如:

了解memory_order_relaxed

memory_order_relaxed 的一些用例是什么

然而,我仍然对memory_order_relaxed的精确语义感到困惑。通常,memory_order_relaxed的示例用例类似于std::shared_ptr——基本上它保留了一个原子计数器,但不需要与其他线程同步。

好的,我的理解如下:

std::memory_order_relaxed,当与load()一起使用时,只保证加载它的线程将以原子方式进行操作-它不保证对同一变量执行store()操作的其他线程的任何排序,也绝对不保证非原子变量的任何加载/存储(即不会生成内存围栏(。

但是,memory_order_relaxed是否提供了任何类型的"发生在之前"类型的排序能力,仅针对的单个原子值?例如,如果我们有:

std::atomic_flag x = ATOMIC_FLAG_INIT;
// Thread A:
//
if (!x.test_and_set(std::memory_order_relaxed)) {
   std::cout << "Thread A got here first!" << std::endl;
}
// Thread B:
//
if (!x.test_and_set(std::memory_order_relaxed)) {
   std::cout << "Thread B got here first!" << std::endl;
}

在上面的例子中,尽管我们使用了memory_order_relaxed,但我们是否也提供了一种有保证的方式来说明在这里订购的原因?换句话说,线程A和线程B都能够推断出哪个线程首先设置了标志。只是,由于排序宽松,线程A和线程B都无法假设任何周围非原子共享变量的值,因为没有内存围栏。还是我在这里不正确?

你是对的。正如您所指出的,在某些用例(如计数器(中,这是可以的。