最終更新日時:
が更新

履歴 編集

class template
<atomic>

std::atomic(C++11)

namespace std {
  template<class T> struct atomic;

  template<> struct atomic<integral>;
  template<class T> struct atomic<T*>;
}

概要

atomicクラステンプレートは、型Tをアトミック操作するためのクラステンプレートである。整数型およびポインタに対する特殊化が提供されており、それぞれに特化した演算が用意されている。その他の型にatomicクラステンプレートを使用する場合、型Ttrivially copyableである必要がある。特殊化された整数型およびbool型には、それぞれatomic_Tという名前のtypedefが提供される。

名前付きアトミック型 テンプレート引数となる整数型
atomic_char char
atomic_schar signed char
atomic_uchar unsigned char
atomic_short short
atomic_ushort unsigned short
atomic_int int
atomic_long long
atomic_ulong unsigned long
atomic_llong long long
atomic_ullong unsigned long long
atomic_char16_t char16_t
atomic_char32_t char32_t
atomic_wchar_t wchar_t
atomic_bool bool

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

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

void*に対する特殊化のtypedefとして、atomic_address型が提供される。

共通メンバ関数

名前 説明
(constructor) コンストラクタ
~atomic() = default デストラクタ
operator= 代入演算子
is_lock_free オブジェクトがロックフリーに振る舞えるかを判定する
store 値を書き込む
load 値を読み込む
operator T 型Tへの変換演算子
exchange 値を入れ替える
compare_exchange_weak 弱い比較で値を入れ替える
compare_exchange_strong 強い比較で値を入れ替える

atomic<integral>専用メンバ関数

名前 説明
fetch_add 加算
fetch_sub 減算
fetch_and AND演算
fetch_or OR演算
fetch_xor XOR演算
operator++ インクリメント
operator-- デクリメント
operator+= 加算
operator-= 減算
operator&= AND演算
operator|= OR演算
operator^= XOR演算

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

名前 説明
fetch_add 加算
fetch_sub 減算
operator++ インクリメント
operator-- デクリメント
operator+= 加算
operator-= 減算

// スピンロックの実装
// 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)

参照