The Atomic Flag

This lesson gives an overview of the atomic flag, which is used from the perspective of concurrency in C++.

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 ATOMIC_FLAG_INIT. std::atomic_flag has two outstanding properties.

std::atomic_flag is:

  • 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 fully utilizes the CPU and does waste CPU cycles.

The example shows the implementation of a spinlock with the help of std::atomic_flag.

Get hands-on with 1000+ tech skills courses.