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宣言が存在しない。