C++ Lock-Free Programming: CAS, ABA, Memory Order, Queues [#34-3]

C++ Lock-Free Programming: CAS, ABA, Memory Order, Queues [#34-3]

이 글의 핵심

Use atomics when mutex contention dominates—know CAS retries, ordering, and safe memory reclamation.

Introduction: mutex contention

Queues under heavy load

Worker pools hammering a mutex-protected queue spend time waiting. Lock-free algorithms use compare-exchange loops so some thread always progresses (lock-free progress guarantee).

Topics: basics, CAS, stack/queue examples, memory_order, ABA, hazards (hazard pointers, epoch reclamation), benchmarks, production cautions.


Lock-free vs wait-free

Lock-free: system-wide progress; some threads may starve in retry loops. Wait-free: per-thread bounded steps—much harder; rare outside simple atomics.


Atomics & CAS

compare_exchange_weak in loops for Treiber stack-style structures. Use acquire/release (or acq_rel) to pair publishes and consumes.

Full LockFreeStack / Michael–Scott listings use acquire/release atomics—copy them carefully so instruction order matches the published algorithms.


Memory order

  • relaxed: counters
  • acquire/release: publish/consume pointers
  • seq_cst: default if unsure (slower)

ABA & reclamation

ABA: node address reused while another thread still thinks it’s valid. Mitigations: hazard pointers, epoch-based reclamation, tagged pointers, or GC integrations—never delete pop’d nodes naively in lock-free pop without a safe reclamation scheme.


Benchmarks

Compare mutex vs lock-free vs SPSC specialized queues on your workload.


Production

Prefer battle-tested libraries (Folly, moodycamel, boost::lockfree) before hand-rolling complex structures.

Keywords

lock-free, compare_exchange, memory_order, ABA, atomic, queue