Skip to content

Can one thread see another's writes out of order?

Level: 201 · anyone who reasoned about threads from the source order

Stub — a question and its expected answers, not yet a lesson. No program behind this page has been written or run, so nothing on it has been through the check that backs every finished page. The table is what the finished lesson is expected to find, and every cell is unverified until a program prints it. (Not machine-checked here.)

One line: A write to data followed by a write to ready can be seen by another thread as ready first — the compiler may reorder them, and the CPU may make them visible in either order — unless the write to ready is a release and the read of it an acquire; the memory model is the contract that says which orders a program may rely on, and it is the same contract in C, C++, Rust and Java, spelled four ways.

The question

Thread A: data = 42; ready = true. Thread B: while !ready {}; print(data). Must B print 42? In the source, yes. On an ARM machine with plain stores, B can print 0. The page runs the store-buffering and message-passing litmus tests under each language's atomics with Relaxed and then with Release/Acquire, and counts the reorderings — as Real runs, since an x86 machine will show almost none and an ARM machine many.

What each language is expected to say

Expected answer, to be verified by the program
Rust Ordering::Relaxed permits the reordering; Release on the store and Acquire on the load forbid it
Go the memory model gives happens-before through channels, mutexes and sync/atomic, and says not to rely on anything weaker
C memory_order_relaxed against memory_order_release/acquire on atomic_bool
C++ the same orderings under the same names; std::atomic defaults to seq_cst
Java volatile gives sequential consistency for the field; a plain field gives nothing
Python one interpreter lock: bytecodes are sequentially consistent, and the question does not arise on CPython

What the programs have to show

  • the message-passing litmus test with relaxed atomics, a million iterations, counting the runs where ready was seen and data was stale — a Real runs fence on x86 and, when available, on arm64
  • the same with release/acquire: zero, and the key
  • the Java volatile and non-volatile field pair

See also