// atomic_flag as a spinning lock
#include <iostream> // std::cout
#include <atomic> // std::atomic_flag
#include <thread> // std::thread
#include <vector> // std::vector
#include <sstream> // std::stringstream
std::atomic_flag lock_stream = ATOMIC_FLAG_INIT;
std::stringstream stream;
void append_number(int x) {
while (lock_stream.test_and_set()) {
}
stream << "thread #" << x << '\n';
lock_stream.clear();
}
int main()
{
std::vector<std::thread> threads;
for (int i = 1; i <= 10; ++i) threads.push_back(std::thread(append_number, i));
for (auto& th : threads) th.join();
std::cout << stream.str();
return 0;
}
上記はatomic_flag
、www.cplusplus.com
与えられたサンプルプログラムを使用して実装された単純なスピンロックです。
常によく理解されているstd::amotic_flag
メンバー関数test_and_set()
がありません。あなたは別の方法で考えることができます。
std::atomic_flag lock_stream = ATOMIC_FLAG_INIT;
初期化された後、false
呼び出されたtest_and_set()
ときlock_stream
です。そうである場合はfalse
、に設定するとtrue
、関数は戻りますfalse
。そうでlock_stream
ある場合はtrue
、設定せずに(すでにtrueであるため)、を返しtrue
ます。
void append_number(int x)
この関数では、lock_stream
ロックが取得されると(つまり、lock_streamが以前はfalseで、trueに設定されている)、lock_stream.test_and_set()
falseを返し、while()ループを終了して、次のコードを実行します。他のスレッドlock_stream.test_and_set()
は、ロックを取得していないために戻りtrue
、ロックが取得されるまでループして試行し、ループを終了します。