memory_order_relaxed的使用

时间:2015-07-02 18:34:53

标签: c++ multithreading c++11 atomic

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都不能假设任何周围的非原子共享变量的值,因为没有内存栅栏。或者我在这里不正确?

1 个答案:

答案 0 :(得分:3)

你是对的。正如您所指出的那样,有一些用例(例如计数器),这很好。