【问题标题】:How to implement CAS in c++11如何在 C++11 中实现 CAS
【发布时间】:2015-06-17 00:58:11
【问题描述】:

我想知道如何在 c++11 中实现 compare_and_swap。 这是我尝试过的:

template<typename T>
T compare_and_swap(atomic<T>& reg,T newVal )
{
    bool success = false;
    T oldVal;
    do
    {
        oldVal = reg.load();
        success = reg.compare_exchange_weak(oldVal,newVal);
    }while(!success);
    return oldVal;
}

有没有更好的方法来实现这个?

【问题讨论】:

  • 你应该尝试在codereview.stackexchange.com提问
  • compare_exchange 已经完成了交换,你根本不需要你的包装器。
  • @Mat 否定,compare_exchange 在某些情况下肯定会添加代码行。需要多次使用 compare_and_swap 语义的情况
  • 我不明白你在说什么。 compare_exchange 是 compare_and_swap,只是一个不同的名字。如果您不想要循环,请使用 strong 变体。
  • 这个compare_and_swap 不等同于标准compare_exchange_strong。后者可能会失败并返回 false,而前者会循环直到成功。这相当于exchange。事实上,对于没有原子交换指令的 CPU,它是 exchange 的有效实现。但它的效率有点低:你不应该在循环内load(),因为你从上一次迭代中获得了更新的值。

标签: c++ c++11


【解决方案1】:

我会这样做:

//untested code
template<typename T>
T compare_and_swap(atomic<T>& reg,T newVal )
{
     oldVal = atomic_load(reg);
     while(!atomic_compare_exchange_weak(&reg, &oldVal, newVal));
     return oldVal;
}

如果失败,比较交换函数将更新 oldval 值。因此没有必要重复这一点。

如您所见,我更喜欢使用显式原子操作。这是因为完整的并不总是被实施。正如 Herb Sutter here 所解释的那样(视频的其余部分您可能也会感兴趣:))。

作为一个可能不必要的事后思考,我想警告不要将此函数与非trivially copyable 类型一起使用。或“正常”指针。共享指针通常没问题:)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2014-08-19
    • 2012-08-06
    • 2013-07-27
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    相关资源
    最近更新 更多