C++ Atomics, Memory Ordering, and Safe Publication

Read the full interview experience this question came from →

Quick Overview

Understand C++ atomics, relaxed counters, acquire-release publication, lost updates, and when multi-field invariants still require a mutex.

C++ Atomics, Memory Ordering, and Safe Publication

Company: Millennium

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

What is an atomic operation in C++, and how is `std::atomic` different from protecting shared state with a mutex? Use a shared counter and a producer publishing a payload to a consumer to explain the difference between atomic access and ordering other memory accesses. Explain why a sequence of atomic operations is not automatically one indivisible transaction. ### Constraints & Assumptions - Use the C++ memory model and `std::atomic`; do not assume an atomic type is always lock-free. - The counter is used only for counting, with no associated payload that its value publishes. - In the publication example, one producer initializes a payload once and signals one consumer with an atomic flag. The producer does not modify that payload afterward. - A hypothetical transfer between two balances requires their combined invariant to be observed consistently. ### Clarifying Questions to Ask - Does this atomic variable only count events, or does it signal that other data is ready? - Are there multiple writers, and can the payload be reused or changed after publication? - Is the requirement atomicity of one field or a transaction across several fields? ```hint Follow the publication edge An atomic ready flag is useful only if observing it also establishes the required ordering for the ordinary payload accesses. ``` ### What a Strong Answer Covers - Indivisible operations on an atomic object and the absence of data races on that object when it is accessed correctly. - An atomic read-modify-write for incrementing a counter, rather than a separate load and store. - The distinction among relaxed, acquire/release, and sequentially consistent ordering. - A correct one-time payload-publication example and why a relaxed flag is insufficient for that example. - Why `volatile`, several atomic fields, and “lock-free” are not substitutes for the needed synchronization contract. ### Follow-up Questions - Why can `counter.store(counter.load() + 1)` lose increments even though both operations are atomic? - What would need to change if the producer repeatedly overwrote the published payload?

Overview: Understand C++ atomics, relaxed counters, acquire-release publication, lost updates, and when multi-field invariants still require a mutex.

Read the full Millennium Software Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/Millennium
Millennium logo
Millennium
Apr 26, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
1
0

What is an atomic operation in C++, and how is std::atomic different from protecting shared state with a mutex?

Use a shared counter and a producer publishing a payload to a consumer to explain the difference between atomic access and ordering other memory accesses. Explain why a sequence of atomic operations is not automatically one indivisible transaction.

Constraints & Assumptions

  • Use the C++ memory model and std::atomic ; do not assume an atomic type is always lock-free.
  • The counter is used only for counting, with no associated payload that its value publishes.
  • In the publication example, one producer initializes a payload once and signals one consumer with an atomic flag. The producer does not modify that payload afterward.
  • A hypothetical transfer between two balances requires their combined invariant to be observed consistently.

Clarifying Questions to Ask Guidance

  • Does this atomic variable only count events, or does it signal that other data is ready?
  • Are there multiple writers, and can the payload be reused or changed after publication?
  • Is the requirement atomicity of one field or a transaction across several fields?

What a Strong Answer Covers Guidance

  • Indivisible operations on an atomic object and the absence of data races on that object when it is accessed correctly.
  • An atomic read-modify-write for incrementing a counter, rather than a separate load and store.
  • The distinction among relaxed, acquire/release, and sequentially consistent ordering.
  • A correct one-time payload-publication example and why a relaxed flag is insufficient for that example.
  • Why volatile , several atomic fields, and “lock-free” are not substitutes for the needed synchronization contract.

Follow-up Questions Guidance

  • Why can counter.store(counter.load() + 1) lose increments even though both operations are atomic?
  • What would need to change if the producer repeatedly overwrote the published payload?
Loading comments...