Concurrency
Studies in this cluster, in series order. Each one keeps its own URL.
Concurrency
Locks, isolation, and the bugs that only show up in production.
Concurrency
6 studies- 1.Mutexes, Condition Variables, Deadlocks & Happens-BeforeMutex HB; CV while-loop (Mesa); Coffman + lock ordering; atomics ≠ compound atomicity; locks vs lock-free.
- 2.Mutex vs RWLockA mutex gives one thread exclusive access. An RWLock (shared mutex) lets many readers in at once or one writer. Reach for an RWLock only when reads far outnumber writes and each read section does real work (I/O, parsing, a long scan), so readers actually overlap. For short critical sections a plain mutex is usually faster: every RWLock reader still does an atomic update on the shared reader count, and that cache line ping-pongs between cores. Default to a mutex and measure before switching.
- 3.Condition Variables: Mesa vs HoareA condition variable lets a thread sleep until a predicate on shared state becomes true, always paired with the mutex that guards that state. Under Hoare semantics, signal hands the mutex straight to the woken waiter, so the predicate is guaranteed true when it runs. Under Mesa semantics (pthreads, Java, C++, Go, Rust, Python), signal is only a hint: the signaler keeps running, the waiter re-acquires the mutex later, and by then the predicate may be false again. So always wait in a while loop, never an if.
- 4.Deadlock Prevention & AvoidanceDeadlock needs Coffman’s four — mutual exclusion, hold-and-wait, no preemption, circular wait. Production systems break circular wait with lock ordering, avoid hold-and-wait with try-lock + backoff, or redesign with channels / actors so resources are not multi-locked.
- 5.Happens-Before & Memory VisibilityHappens-before (≺) is the relation that makes writes visible and ordered across threads. Mutex unlock ≺ later lock; volatile/atomic stores synchronize with later loads; thread start/join create edges. Without a happens-before edge, seeing stale/torn values is allowed.
- 6.Atomics vs LocksA lock protects an invariant that spans several fields and makes waiters block. An atomic does one read-modify-write on one machine word (load, store, fetch_add, compare-and-swap) without blocking anyone. Use atomics for single-word counters, flags and published pointers; use a lock as soon as two fields must change together, because making each field atomic does not make the group atomic. Neither removes contention on one hot word: atomics fail by retrying while the cache line bounces, locks fail by queueing.