CC Explainer
C · 6 · Advanced / Job-Ready31 / 35 · 89%

C11 Atomics & Memory Ordering

Lock-free counters and the ordering guarantees that make them correct.

Examples: _Atomic, atomic_fetch_add, memory_order

shortcuts: ← prev · → next · M mark
1

Atomic Types

Read-modify-write in one indivisible step.

Example
example
#include <stdatomic.h>

_Atomic int counter = 0;
atomic_fetch_add(&counter, 1);        // seq_cst by default
int now = atomic_load(&counter);
atomic_store(&counter, 0);
2

Why ++ Is Not Atomic

One line of C is three machine steps.

counter++ (plain int)
stepop
1load
2add 1
3store
→
atomic_fetch_add
stepop
1lock xadd
indivisible
no lost update
Two threads interleaving the load/add/store lose increments.
3

Memory Orders

Weaker orders are faster but harder to reason about.

Example
example
atomic_fetch_add(&hits, 1, memory_order_relaxed);   // counter only
atomic_store(&ready, 1, memory_order_release);     // publish
if (atomic_load(&ready, memory_order_acquire)) { } // consume
TIP
Default to seq_cst. Only weaken to acquire/release after you have measured a real bottleneck.
4

Compare-and-Swap

The building block of every lock-free algorithm.

Example
example
int expected = old;
while (!atomic_compare_exchange_weak(&value, &expected, expected + 1)) {
    // expected was reloaded with the current value — retry
}
Interview question
When is a lock-free structure worse than a mutex?