The Atomic Flag
The atomic flag, i.e.
std::atomic_flag, has a very simple interface. Its
clear method enables you to set its value to
false; with the
test_and_set method you can set the value back to
true. There is no method to exclusively ask for the current value. To use
std::atomic_flag it must be initialized to
false with the constant
std::atomic_flag has two outstanding properties.
- the only lock-free atomic. A non-blocking algorithm is lock-free if there is guaranteed system-wide progress.
- the building block for higher level thread abstractions.
The only lock-free atomic? The remaining more powerful atomics can provide their functionality by using a mutex internally according to the C++ standard. These remaining atomics have a method called
is_lock_free to check if the atomic uses a mutex internally. On the popular microprocessor architectures, I always get the answer
true. That being said, my implementation internally uses no mutex; you should be aware of this and check it on your target system if you want to program lock-free.
The interface of
std::atomic_flag is powerful enough to build a spinlock. With a spinlock, you can protect a critical section as you would with a mutex. The spinlock will not passively wait, in contrast to a mutex, until it gets it to lock. It will eagerly ask for the lock to get access to the critical section.it fully utilizes the CPU and does waste CPU cycles.
The example shows the implementation of a spinlock with the help of