【问题标题】:C++11 atomic library std::compare_and_exchange semanticsC++11 原子库 std::compare_and_exchange 语义
【发布时间】:2014-07-19 19:30:02
【问题描述】:

如果sequenceNumberatomic<int>(seq_no 只是一个整数),

为什么

sequenceNumber.compare_exchange_strong(sequenceNumber, seq_no );

不编译?

我在compare_exchange_strong 操作之前对原子变量sequenceNumber 进行了比较操作,并想检查当我真正在我的线程中更新它时,sequenceNumber 的值是否已被另一个线程更改。

类似这样的:

if ( seq_no > sequenceNumber )
      sequenceNumber.compare_exchange_strong(sequenceNumber, seq_no);

我通过以下方式修复它:

int current_sequence_number = sequenceNumber.load();
if ( seq_no > current_sequence_number )
    sequenceNumber.compare_exchange_strong(current_sequence_number, seq_no );

但我想知道为什么编译器不允许我使用atomic<int> 代替第一个参数,即函数调用中的“预期”参数 -

bool compare_exchange_strong( T& expected, T desired,
                              std::memory_order order = 
                                  std::memory_order_seq_cst ); 

不允许使用原子变量代替预期参数的动机是什么,尤其是当 seq_no > sequenceNumber 似乎被允许时?

顺便说一句,使用seq_no > sequenceNumber 也是错误的吗? (即使它编译)在这种情况下我也应该选择seq_no > sequenceNumber.load() 吗?

【问题讨论】:

  • 什么是sequenceNumber?以何种方式(如果有的话)与sequence_number 相关?
  • @IgorTandetnik 这些是错别字。我修好了它们。我真的,真的很对不起他们。请您再看一下这个问题吗?
  • atcmic<T> 提供了一个转换operator T(),它与load() 做同样的事情。这就是为什么您可以在需要T 值的任何地方使用atomic<T> 的实例。 seq_no > sequence_number 等价于 seq_no > sequence_number.load()
  • 好的,但是为什么operator T() 不适用于compare_exchange_strong
  • operator T() 为您提供T 类型的右值。 compare_exchange_strong 需要一个左值 - 一个非常量引用。 atomic<T> 无法转换为 T&。如果它允许直接访问底层存储,您可以绕过其“原子性”对其进行修改。对于原子而言,每次加载和存储都很重要,因为它们会影响与其他线程的同步。

标签: c++ c++11 concurrency atomic


【解决方案1】:

atomic<T>::compare_exchange_strongT& 作为其第一个参数。 atomic<T> 不能转换为T&(即使它可以转换为T 类型的右值;这种转换只调用load())。

如果atomic<T> 可转换为T&,它将有效地提供对底层原始存储的无限制访问,并允许用户随意修改它,绕过任何同步机制。这将彻底破坏首先拥有atomic 的意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多