Skip to content

Latest commit

 

History

History
195 lines (147 loc) · 9.33 KB

atomic_ref.md

File metadata and controls

195 lines (147 loc) · 9.33 KB

atomic_ref

  • atomic[meta header]
  • std[meta namespace]
  • class template[meta id-type]
  • cpp20[meta cpp]
namespace std {
  template<class T> struct atomic_ref;          // (1) C++20

  template<> struct atomic_ref<integral>;       // (2) C++20
  template<> struct atomic_ref<floating-point>; // (3) C++20
  template<class T> struct atomic_ref<T*>;      // (4) C++20
}
  • integral[italic]
  • floating-point[italic]

概要

atomic_refクラステンプレートは、コンストラクタで受け取ったT型変数への参照に対してアトミック操作を適用する型である。非アトミックなオブジェクトに対して、値コピーによるstd::atomic型変換の必要なく、アトミック操作を適用する。

オブジェクトが、多くの場面で非アトミックに使用され、競合回避のためにアトミックに振る舞う必要があるのが一部の場面である場合、オブジェクトを強制的にアトミックオブジェクトに変換してしまうことは、パフォーマンス低下につながる。atomic_refクラスを使用することで、そのような状況に対応し、一部の状況でのみオブジェクトをアトミックに振る舞わせることができる。

同じオブジェクトを参照する異なるatomic_refオブジェクトを介して行われるアトミック操作は、共通の参照するオブジェクトに対してアトミックに行われる。つまり、局所的にatomic_refオブジェクトに変換してアトミック操作を適用してもよい。

オブジェクトを参照してアトミック操作をするための制約として、アーキテクチャ固有のアライメント制約を満たすことが要求される。コンストラクタと代入演算子でオブジェクトを参照する際、メンバ定数としてのアライメント値required_alignmentの位置にオブジェクトが配置されていること。

atomic_refクラステンプレートは型Tの値をコピーではなく参照で保持するため、atomic_refオブジェクトより先に参照先の変数の寿命が尽きてはならない。

  • (1) : プライマリテンプレート。宣言のみ
  • (2) : 整数型に対する特殊化
  • (3) : (CV修飾されていない) 浮動小数点数型に対する特殊化
    • (C++23) : 拡張浮動小数点数型を含む
  • (4) : 任意の型のポインタに対する特殊化

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

メンバ関数

共通メンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ C++20
~atomic_ref() = default デストラクタ C++20
operator= 代入 C++20
is_lock_free オブジェクトがロックフリーに振る舞えるかを判定する C++20
store 値を書き込む C++20
load 値を読み込む C++20
operator T 型Tへの変換演算子 C++20
exchange 値を入れ替える C++20
compare_exchange_weak 弱い比較で値を入れ替える C++20
compare_exchange_strong 強い比較で値を入れ替える C++20
wait 起床されるまで待機する C++20
notify_one 待機しているスレッドをひとつ起床させる C++20
notify_all 待機している全てのスレッドを起床させる C++20

共通メンバ型

名前 説明 対応バージョン
value_type 要素型となるテンプレートパラメータの型T C++20

共通メンバ定数

名前 説明 対応バージョン
static constexpr bool is_always_lock_free Tに対するアトミック操作が常にロックフリー (非ミューテックス) で動作する場合はtrue、そうでなければfalse C++20
static constexpr size_t required_alignment 参照するオブジェクトに要求されるアライメント。少なくともalignof(T) C++20

is_always_lock_free == trueの場合、このクラスのオブジェクトをシグナルハンドラー内で使用できる。

required_alignmentについて、ハードウェアは参照するオブジェクトに対して、型Tのほかのオブジェクトよりも厳密なアライメントを持つことを要求できる。また、atomic_refがロックフリーかどうかは、参照するオブジェクトのアライメントに依存する。たとえばstd::complex<double>のロックフリー操作は2 * alignof(double)にアライメントされる場合にのみサポートされる。

atomic_ref<integral>専用メンバ関数

整数型に対する特殊化。

名前 説明 対応バージョン
fetch_add 加算 C++20
fetch_sub 減算 C++20
fetch_and AND演算 C++20
fetch_or OR演算 C++20
fetch_xor XOR演算 C++20
operator++ インクリメント C++20
operator-- デクリメント C++20
operator+= 加算 C++20
operator-= 減算 C++20
operator&= AND演算 C++20
operator|= OR演算 C++20
operator^= XOR演算 C++20

atomic_ref<integral>専用メンバ型

名前 説明 対応バージョン
difference_type 2つの値の差を表す整数型value_type C++20

atomic_ref<floating-point>専用メンバ関数

浮動小数点数型に対する特殊化。

名前 説明 対応バージョン
fetch_add 加算 C++20
fetch_sub 減算 C++20
operator+= 加算 C++20
operator-= 減算 C++20

atomic_ref<floating-point>専用メンバ型

名前 説明 対応バージョン
difference_type 2つの値の差を表す整数型value_type C++20

atomic_ref<T*>専用メンバ関数

ポインタ型に対する特殊化。

名前 説明 対応バージョン
fetch_add 加算 C++20
fetch_sub 減算 C++20
operator++ インクリメント C++20
operator-- デクリメント C++20
operator+= 加算 C++20
operator-= 減算 C++20

atomic_ref<T*>専用メンバ型

名前 説明 対応バージョン
difference_type 2つの値の差を表す整数型ptrdiff_t C++20

#include <iostream>
#include <atomic>
#include <thread>

struct Info {
  int value = 0;
};

int main()
{
  Info info;

  std::thread consumer_thread {[&info] {
    std::atomic_ref<int> x{info.value};
    while (true) {
       if (int value = x.exchange(0); value != 0) {
         std::cout << value << std::endl;
         break;
       }
    }
  }};

  std::atomic_ref{info.value}.store(3); // クラステンプレートのテンプレート引数推論も使用できる (<int>省略)
  consumer_thread.join();
}
  • std::atomic_ref[color ff0000]
  • x.exchange[link atomic_ref/exchange.md]
  • store[link atomic_ref/store.md]
  • consumer_thread.join()[link /reference/thread/thread/join.md]

出力

3

バージョン

言語

  • C++20

処理系

関連項目

参照