• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

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

    履歴 編集

    class template
    <atomic>

    std::atomic

    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
    }
    

    概要

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

    • (1) : プライマリテンプレート。宣言のみ
    • (2) : 整数型に対する特殊化
    • (3) : (CV修飾されていない) 浮動小数点数型に対する特殊化
    • (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

    処理系

    備考

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

    関連項目

    参照