std::atomic_flag
From cppreference.com
| ヘッダー <atomic> で定義 |
||
| class atomic_flag; |
(C++11以降) | |
std::atomic_flagはアトミックな真偽値型である。std::atomicの全ての特殊化とは異なり、ロックフリーであることが保証されている。std::atomic<bool>とは異なり、std::atomic_flagはloadやstore操作を提供しない。
[編集] メンバ関数
| atomic_flagを構築する (public member function) | |
| [削除] |
代入演算子(削除) (public member function) |
| フラグをアトミックにfalseに設定する (public member function) | |
| フラグをアトミックにtrueに設定し、以前の値を取得する (public member function) | |
| (C++20) |
フラグの値をアトミックに返す (public member function) |
| (C++20) |
通知されるまで、かつアトミックな値が変更されるまでスレッドをブロックする (public member function) |
| (C++20) |
アトミックオブジェクトを待機しているスレッドを少なくとも1つ通知する (public member function) |
| (C++20) |
アトミックオブジェクトを待機してブロックされている全てのスレッドに通知する (public member function) |
[編集] 例
スピンロックミューテックスのデモは、atomic_flagを使ってユーザースペースで実装できる。スピンロックミューテックスは、実際には極めて疑わしいことに注意すること。
このコードを実行
#include <atomic> #include <iostream> #include <mutex> #include <thread> #include <vector> class mutex { std::atomic_flag m_{}; public: void lock() noexcept { while (m_.test_and_set(std::memory_order_acquire)) #if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L // Since C++20, locks can be acquired only after notification in the unlock, // avoiding any unnecessary spinning. // Note that even though wait guarantees it returns only after the value has // changed, the lock is acquired after the next condition check. m_.wait(true, std::memory_order_relaxed) #endif ; } bool try_lock() noexcept { return !m_.test_and_set(std::memory_order_acquire); } void unlock() noexcept { m_.clear(std::memory_order_release); #if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L m_.notify_one(); #endif } }; static mutex m; static int out{}; void f(std::size_t n) { for (std::size_t cnt{}; cnt < 40; ++cnt) { std::lock_guard lock{m}; std::cout << n << ((++out % 40) == 0 ? '\n' : ' '); } } int main() { std::vector<std::thread> v; for (std::size_t n{}; n < 10; ++n) v.emplace_back(f, n); for (auto &t : v) t.join(); }
実行結果の例
0 1 1 2 0 1 3 2 3 2 0 1 2 3 2 3 0 1 3 2 0 1 2 3 2 3 0 3 2 3 2 3 2 3 1 2 3 0 1 3 2 3 2 0 1 2 3 0 1 2 3 2 0 1 2 3 0 1 2 3 2 3 2 3 2 0 1 2 3 2 3 0 1 3 2 3 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 3 2 0 2 3 2 3 2 3 2 3 2 3 0 3 2 3 0 3 0 3 2 3 0 3 2 3 2 3 0 2 3 0 3 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
[編集] 関連項目
| フラグをアトミックにtrueに設定し、以前の値を返す (function) | |
| (C++11)(C++11) |
フラグの値をアトミックにfalseに設定する (function) |
| (C++20)(C++20) |
通知されるまで、かつフラグが変更されるまでスレッドをブロックする (function) |
| (C++20) |
atomic_flag_waitでブロックされているスレッドに通知する (function) |
| (C++20) |
atomic_flag_waitでブロックされている全てのスレッドに通知する (function) |
| (C++11) |
std::atomic_flagをfalseに初期化する (macro constant) |
| Cのドキュメント atomic_flagについて
| |