Stackoverflow上已经有一些问题基本上会询问memory_order_relaxed
的用例,例如:
Understanding memory_order_relaxed
What are some use cases for 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都不能假设任何周围的非原子共享变量的值,因为没有内存栅栏。或者我在这里不正确?
答案 0 :(得分:3)
你是对的。正如您所指出的那样,有一些用例(例如计数器),这很好。