Share Flags and Values with std::atomic

Learn to share flags and values with std::atomic.

The std::atomic class encapsulates a single object and guarantees it to be atomic. Writing to the atomic object is controlled by memory-order policies and reads may occur simultaneously. It's typically used to synchronize access among different threads.

std::atomic defines an atomic type from its template type. The type must be trivial. A type is trivialIn programming, trivial refers to a construct or operation that is straightforward, simple, or requires minimal effort or complexity to implement or understand. if it occupies contiguous memory, has no user-defined constructor, and has no virtual member functions. All primitive types are trivial. While it is possible to construct a trivial type, std::atomic is most often used with simple primitive types, such as bool, int, long, float, and double.

How to do it

This recipe uses a simple function that loops over a counter to demonstrate sharing atomic objects. We will spawn a swarm of these loops as threads that share atomic values:

  • Atomic objects are often placed in a global namespace. They must be accessible to all the threads that need to share its value:

std::atomic<bool> ready{};
std::atomic<uint64_t> g_count{};
std::atomic_flag winner{};

The ready object is a bool type that gets set to true when all the threads are ready to start counting. The g_count object is a global counter. It is incremented by each of the threads. The winner object is a special atomic_flag type. It is used to indicate which thread finishes first.

  • We use a couple of constants to control the number of threads and the number of loops for each thread:

constexpr int max_count{1000 * 1000};
constexpr int max_threads{100};

Here, we've set it to run 100100 ...

Get hands-on with 1400+ tech skills courses.