Skip to main content

Atomics and the Three Orderings

advanced12 min readLesson 160 of 204

std::atomic makes single variables race-free; memory_order decides how much other memory gets synchronized with it.

What atomic buys

std::atomic<int> x; โ€” every read-modify-write is indivisible, and concurrent access is not UB. But atomicity is the cheap part. The deep part is ordering: what do other threads see of surrounding memory when this atomic transfer happens?

The three orderings, least to most

memory_order_relaxed โ€” atomicity only. No synchronization of other memory, no ordering promises beyond this one variable. Perfect for event counters, statistics โ€” where "the number is right eventually" is the whole requirement:

std::atomic<int> hits{0};
++hits;   // fetch_add 1, relaxed by default via operator form? no โ€” operator++ IS seq_cst;
          // pass the order explicitly: hits.fetch_add(1, std::memory_order_relaxed);

memory_order_acquire / memory_order_release โ€” the workhorse pair. A release store makes everything this thread did before the store visible to any thread that later does an acquire load reading that value:

std::atomic<bool> ready{false};
int payload = 0;

// producer
payload = 42;                                   // ordinary write
ready.store(true, std::memory_order_release);   // publish

// consumer
while (!ready.load(std::memory_order_acquire)) {}
// payload == 42 is GUARANTEED here โ€” acquire/release ordered the ordinary write

memory_order_seq_cst โ€” the default, strongest: all seq_cst operations across all threads agree on one global order. Easiest to reason about, most expensive. Default when unsure; relax only with a written reason.

The exercise rule

The graded work follows the professional discipline: relaxed where only atomicity matters, acquire/release for publish-consume of payload data, seq_cst when threads must agree on a total order.

Now practice

Ordering SelectionRelaxed vs acquire/release vs seq_cst on real micro-protocols โ€” the ordering muscle memory.1 challenge ยท ยท ~18 min