最終更新日時(UTC):
が更新

履歴 編集

function template
<atomic>

std::atomic_compare_exchange_weak_explicit(C++11)

namespace std {
  template <class T>
  bool atomic_compare_exchange_weak_explicit(
         volatile atomic<T>* object,
         T* expected,
         T desired,
         memory_order success,
         memory_order failure) noexcept;       // (1) C++11

  template <class T>
  bool atomic_compare_exchange_weak_explicit(
         volatile atomic<T>* object,
         typename atomic<T>::value_type* expected,
         typename atomic<T>::value_type desired,
         memory_order success,
         memory_order failure) noexcept;       // (1) C++17

  template <class T>
  bool atomic_compare_exchange_weak_explicit(
         atomic<T>* object,
         T* expected,
         T desired,
         memory_order success,
         memory_order failure) noexcept;       // (2) C++11

  template <class T>
  bool atomic_compare_exchange_weak_explicit(
         atomic<T>* object,
         typename atomic<T>::value_type* expected,
         typename atomic<T>::value_type desired,
         memory_order success,
         memory_order failure) noexcept;       // (2) C++17
}

概要

弱い比較でアトミックに値を入れ替える

テンプレートパラメータ制約

  • (1) :
    • C++20 : atomic<T>::is_always_lock_freetrueであること

事前条件

効果

現在の値*objectexpectedをバイトレベルで等値比較を行い、trueである場合は現在の値*objectdesiredで置き換え、falseである場合は*expectedを現在の値*objectで置き換える。

バイト等値比較がtrueの場合はsuccessメモリオーダー、falseの場合はfailureメモリオーダーに従って、アトミックに値の置き換えが行われる。

戻り値

等値比較の結果が返される

例外

投げない

備考

この関数は、値が交換可能な場合でもCAS (compare-and-swap)操作が失敗する可能性がある。

atomic_compare_exchange_strong_explicit()はより強い命令であり、交換可能な場合はCAS操作が常に成功する。

アーキテクチャによっては、この関数はatomic_compare_exchange_strong_explicit()と等価だが、PowerPCやARMなどLL/SC命令を提供するアーキテクチャの場合、この関数はハードウェアの“弱いLL/SC命令”にて実装されうる。wikipedia:en:Load-link/store-conditional, wikipedia:Load-Link/Store-Conditional などを参照のこと。

通常、CAS操作は、CASが成功するまでループさせる。

しかし、もしCAS操作でSpurious Failureが発生しなければループさせる必要が無くなるといった状況であれば、atomic_compare_exchange_strong_explicit()を使うことで効率良くCASを行うことができる。

逆に言えば、そのような状況でないなら常にループでatomic_compare_exchange_weak_explicit()を利用すれば良い。

#include <iostream>
#include <atomic>

int main()
{
  {
    std::atomic<int> x(3);

    // x == expectedなので、xは2に置き換えられる
    int expected = 3;
    bool result = std::atomic_compare_exchange_weak_explicit(&x, &expected, 2,
                                                             std::memory_order_acquire,
                                                             std::memory_order_acquire);

    std::cout << std::boolalpha << result << " " << x.load() << " " << expected << std::endl;
  }
  {
    std::atomic<int> x(3);

    // x != expectedなので、expectedがxの値で置き換えられる
    int expected = 1;
    bool result = std::atomic_compare_exchange_weak_explicit(&x, &expected, 2,
                                                             std::memory_order_acquire,
                                                             std::memory_order_acquire);

    std::cout << std::boolalpha << result << " " << x.load() << " " << expected << std::endl;
  }
}

出力

true 2 3
false 3 3

バージョン

言語

  • C++11

処理系

関連項目

参照