提问者:小点点

如何原子更新一个最大值?


在串行代码中,更新最大值可以简单地通过以下方式实现

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

但是,对于保存最大值的atomic变量,应该如何执行此操作:

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的实现中可能附带的锁)。


共1个答案

匿名用户

在一次操作中似乎不可能做到这一点,但您可以创建一个循环,尝试这样做,直到它最终成功或原子变量中的值大于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))
        {}
}