// 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;
}
The above is atomic_flag
a simple spin lock implemented using www.cplusplus.com
the example program given.
std::amotic_flag
The member function test_and_set()
that has always been well understood is not in place. You can think in another way.
std::atomic_flag lock_stream = ATOMIC_FLAG_INIT;
After being initialized , it is when it is false
called test_and_set()
. If it lock_stream
is false
, set it to true
, and then the function returns false
; if it lock_stream
is true
, do not set it (because it is already true) and return true
.
void append_number(int x)
In the function, when the lock_stream
lock is acquired (that is, the lock_stream is false before and is set to true), it lock_stream.test_and_set()
returns false, exits the while() loop, and executes the following code. Other threads lock_stream.test_and_set()
return because they have not acquired the lock, true
and then loop to try until the lock is acquired and exit the loop.