45

在串行代码中,更新最大值可以简单地通过

template<typename T>
void update_maximum(T& maximum_value, T const& value) noexcept
{
  if(value > maximum_value) maximum_value = value;
}

atomic<T>但是,对于保持最大值的变量,应该如何做到这一点:

template<typename T>
void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept
{
   // want a lock-free, thread-safe implementation
}

显然,串行版本的代码不起作用,因为另一个线程可能会maximum_value在加载和存储之间改变。可以使用compare_exchange(比较==而不是>)来实现这一点吗?如何?

请注意,不允许使用显式锁(唯一允许的锁是 的实现可能附带的锁std::atomic<T>)。

4

1 回答 1

49

在单个操作中似乎不可能,但是您可以创建一个循环,尝试执行此操作,直到它最终成功或原子变量中的值变得大于value

template<typename T>
void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept
{
    T prev_value = maximum_value;
    while(prev_value < value &&
            !maximum_value.compare_exchange_weak(prev_value, value))
        {}
}
于 2013-04-24T11:28:25.410 回答