最終更新日時: 2025年07月12日 02時16分44秒 (JST)
Koichi Murase が更新

履歴 編集

class
<atomic>

# std::atomic_flag(C++11)

    namespace std {
      struct atomic_flag;
    }

## 概要

`atomic_flag`クラスは、フラグを表現するためのアトミッククラスである。このクラスは、シンプルなtest-and-set (TAS) 機能を提供し、有効値の設定とクリアの2状態のみを持つ。このクラスに対する操作はロックフリーであることが保証される。（機能的には`atomic<bool>`クラスよりも貧弱だが、`atomic_flag`クラスの操作は必ずロックフリーである点が異なる。）

### メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++11
`~atomic_flag() = default` | デストラクタ | C++11
`operator=(const atomic_flag&) = delete` `operator=(const atomic_flag&) volatile = delete` | 代入演算子 | C++11
`test` | 現在の値をbool値として取得する | C++20
`test_and_set` | テストしてフラグを立てる | C++11
`clear` | フラグをクリアする | C++11
`wait` | 起床されるまで待機する | C++20
`notify_one` | 待機しているスレッドをひとつ起床させる | C++20
`notify_all` | 待機している全てのスレッドを起床させる | C++20

### 例

    // スピンロックの実装
    #include <iostream>
    #include <atomic>
    #include <thread>
    #include <mutex>

    class spinlock {
    private:
      std::atomic_flag state_;

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

      void lock()
      {
        // 現在の状態をロック状態にする
        while (state_.test_and_set(std::memory_order_acquire)) {
          // busy-wait...アンロックされるまで待機
        }
      }

      void unlock()
      {
        // 値をアンロック状態にする
        state_.clear(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: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2012 ✅, 2013 ✅
  - 2012はコピーコンストラクタと代入演算子のdelete宣言が存在しない。

### 参照