Engineering and capstones · 51 / 53
Concurrent structures, atomics and ABA
Understand → trace → implement → justify
2 min reading · allow extra time for practiceA linked list correct in one thread can fail under concurrent updates. One atomic instruction does not make a multi-step operation atomic. Linearizability requires each operation to appear instantaneous between invocation and response. Mutex designs need lock scope, ordering and exception-safe release.
Lock-free means system-wide progress; wait-free bounds each operation’s steps. Neither automatically means fast. CAS retries under contention. ABA changes an address A→B→A, hiding intervening changes from a simple comparison. Version tags, hazard pointers and epoch reclamation address related but distinct issues, including safe reuse.
Acquire/release and relaxed operations provide different visibility guarantees. The Python GIL is not a portable guarantee for every compound operation or runtime. C# Interlocked differs from Volatile. Tests need invariants and failure scheduling beyond stress runs. Production lock-free code requires a memory-model argument.
A worked trace
Two workers read 10 and both write 11: one increment is lost. Lock the entire read-modify-write.
Cost and assumptions
Contention and scheduler delay are absent from sequential Big-O; measure latency distributions.
Executable example
Run with Python 3. Assertions check a small example; they do not constitute a general correctness proof. Some advanced examples are explicitly small models or reference oracles, not full production implementations.
from threading import Lock,Thread
lock=Lock(); counter=0
def work():
global counter
for _ in range(1000):
with lock: counter+=1
threads=[Thread(target=work) for _ in range(4)]
for t in threads:t.start()
for t in threads:t.join()
assert counter==4000TEST YOUR UNDERSTANDING
Your turn
Does this passing test prove a lock-free alternative correct?
Reveal the reasoning
No. This code uses a mutex, and finite stress does not prove all interleavings.
Take it further
- Write down the input contract and the invariant before changing the example.
- Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
- Derive the cost under the stated model; measure several input sizes and explain discrepancies.
Primary reading & lecture notes
Original explanations in this course; these references provide proofs and further reading. Source links may cover the broader module.
Pat Morin · Open Data Structures ↗