Skip to content

Latest commit

 

History

History
316 lines (252 loc) · 15.2 KB

atomic.md

File metadata and controls

316 lines (252 loc) · 15.2 KB

atomic

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

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

概要

atomicクラステンプレートは、型Tをアトミック操作するためのクラステンプレートである。組み込み型に対する特殊化が提供されており、それぞれに特化した演算が用意されている。

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

これらのほか、<memory>ヘッダでstd::shared_ptrstd::weak_ptrに対するatomicクラスの特殊化が定義される。

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

別名型

特殊化された整数型およびbool型には、それぞれatomic_Tという型の別名が提供される。

名前付きアトミック型 テンプレート引数となる整数型 対応バージョン
atomic_char char C++11
atomic_schar signed char C++11
atomic_uchar unsigned char C++11
atomic_short short C++11
atomic_ushort unsigned short C++11
atomic_int int C++11
atomic_uint unsigned int C++11
atomic_long long C++11
atomic_ulong unsigned long C++11
atomic_llong long long C++11
atomic_ullong unsigned long long C++11
atomic_char8_t char8_t C++20
atomic_char16_t char16_t C++11
atomic_char32_t char32_t C++11
atomic_wchar_t wchar_t C++11
atomic_bool bool C++11

浮動小数点数型に対する別名は定義されていない。

また、<cstdint>で定義される整数型に対する以下の別名も提供される。

名前付きアトミック型 テンプレート引数となる整数型 対応バージョン
atomic_int_least8_t int_least8_t C++11
atomic_uint_least8_t uint_least8_t C++11
atomic_int_least16_t int_least16_t C++11
atomic_uint_least16_t uint_least16_t C++11
atomic_int_least32_t int_least32_t C++11
atomic_uint_least32_t uint_least32_t C++11
atomic_int_least64_t int_least64_t C++11
atomic_uint_least64_t uint_least64_t C++11
atomic_int_fast8_t int_fast8_t C++11
atomic_uint_fast8_t uint_fast8_t C++11
atomic_int_fast16_t int_fast16_t C++11
atomic_uint_fast16_t uint_fast16_t C++11
atomic_int_fast32_t int_fast32_t C++11
atomic_uint_fast32_t uint_fast32_t C++11
atomic_int_fast64_t int_fast64_t C++11
atomic_uint_fast64_t uint_fast64_t C++11
atomic_size_t size_t C++11
atomic_ptrdiff_t ptrdiff_t C++11
atomic_intmax_t intmax_t C++11
atomic_uintmax_t uintmax_t C++11

以下の整数型に対する別名は、整数型に対するatomic型の特殊化だが、その中でも以下の特性を持つものである:

  • is_always_lock_freeプロパティがtrueである
  • wait/notify操作が最も効率的に行える整数アトミック型

ただし、フリースタンディング環境において、これらの型は定義されない場合がある。

名前付きアトミック型 説明 対応バージョン
atomic_signed_lock_free is_always_lock_free == trueかつwait/notify操作が最も効率的に行える符号付き整数のアトミック型 C++20
atomic_unsigned_lock_free is_always_lock_free == trueかつwait/notify操作が最も効率的に行える符号なし整数のアトミック型 C++20

<cstdint>で定義される整数型に対する以下の別名は、元の整数型が定義される場合のみ定義される。

名前付きアトミック型 テンプレート引数となる整数型 対応バージョン
atomic_int8_t int8_t C++17
atomic_uint8_t uint8_t C++17
atomic_int16_t int16_t C++17
atomic_uint16_t uint16_t C++17
atomic_int32_t int32_t C++17
atomic_uint32_t uint32_t C++17
atomic_int64_t int64_t C++17
atomic_uint64_t uint64_t C++17
atomic_intptr_t intptr_t C++11
atomic_uintptr_t uintptr_t C++11

メンバ関数

共通メンバ関数

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

共通メンバ型

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

共通メンバ定数

名前 説明 対応バージョン
static constexpr bool is_always_lock_free Tに対するアトミック操作が常にロックフリー (非ミューテックス) で動作する場合はtrue、そうでなければfalse C++17

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

atomic<integral>専用メンバ関数

整数型に対する特殊化。

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

atomic<integral>専用メンバ型

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

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

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

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

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

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

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

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

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

atomic<T*>専用メンバ型

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

// スピンロックの実装
// Boost Atomic Library - Usage Example
// http://www.boost.org/doc/libs/1_53_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_spinlock

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

class spinlock {
private:
  enum LockState {Locked, Unlocked};
  std::atomic<LockState> state_;

public:
  spinlock() : state_(Unlocked) {}

  void lock()
  {
    // 現在の状態をLockedと入れ替える
    while (state_.exchange(Locked, std::memory_order_acquire) == Locked) {
      // busy-wait...アンロックされるまで待機
    }
  }

  void unlock()
  {
    // 値をUnlockedに更新
    state_.store(Unlocked, std::memory_order_release);
  }
};

namespace {
  spinlock lock;
}

template <class T>
void print(const T& x)
{
  std::lock_guard<spinlock> lk(lock);
  std::cout << x << std::endl;
}

void f()
{
  print(1);
}

void g()
{
  print(2);
}

int main()
{
  std::thread t1(f);
  std::thread t2(g);

  t1.join();
  t2.join();
}

出力例

2
1

バージョン

言語

  • C++11

処理系

  • Clang: 3.2 [mark verified]
  • GCC: 4.7.0 [mark verified]
  • Visual C++: 2012 [mark verified], 2013 [mark verified]

備考

  • GCC 4.9.2まで、アライメントがおかしくなってセグメンテーションフォルトになるバグがあった。GCC 5.1で修正された。(Bug 65147)

関連項目

参照