シリアルコードでは、最大値の更新は次の方法で簡単に実行できます。
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>
の実装に付属しているロックのみです)。
単一の操作では不可能なようですが、最終的に成功するか、アトミック変数の値が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))
{}
}