C ++ 11比较和交换获取/释放语义

时间:2012-08-01 16:26:21

标签: c++ c++11 atomic

我们假设我有以下代码(玩具示例):

std::atomic<K *> data;
K *old_value = NULL;
K *new_value = new K();
if (!data.compare_exchange_strong(old_value, new_value, m1, m2)) {
    delete new_value;
}
do_something(old_value);

或者

std::atomic<K *> data;
K *i = data.load(m3);
K *j;
do {
   j = i + 1;
} while (data.compare_exchange_weak(i, j, m4, m5);
do_something(j);

m1m2m3m4m5的有效值是多少? 我的阅读是所有都可以std::memory_order_relaxed,因为整个代码强烈依赖于先前操作的结果(假设do_something只使用指针而不改变全局共享状态)。我的阅读是否正确?

1 个答案:

答案 0 :(得分:4)

这个问题仅在具有明确定义的共享状态的多线程场景中才有意义。在不知道其他线程做什么的情况下,我只能假设它读/写data。只需要这个单一的同步点,所有宽松的排序应该可以。对于任何独立于其他同步点考虑的给定原子,操作仍然是原子的,它们的相对顺序仍然是正确的。

现在,如果共享状态由几个变量组成(那就是“排序”发挥作用),那将是一个完全不同的故事;你必须担心获得/释放/等。语义。在这种情况下:

relaxed

  • 不保证来自一个线程的多个变量的更改对于同一订单中的另一个线程是可见的;
  • 不保证对来自不同线程(例如,线程1集data1和线程2集data2)的多个变量的更改将以相同顺序对所有其他线程可见

acquire/release(分别在每次读/写时使用;对于不同的排序参数模式,第一项可能会变得更加宽松)

  • 保证来自一个线程的多个变量的更改将以相同的顺序显示给另一个线程;
  • 不保证对来自不同线程的多个变量的更改对于同一订单中的所有其他线程都是可见的。

seq_cst(再次,在每次读/写时使用):

  • 保证来自一个线程的多个变量的更改将以相同的顺序显示给另一个线程;
  • 保证对不同线程独立的多个变量的更改将以相同的顺序显示给所有其他线程,无论它是什么。