๐ WAYPOINT LESSON
Mutexes, rwlocks, condvars โ and what each one costs
โญโญโญ advancedโณ 18 min read๐ Lesson 205 of 225
Choosing a synchronization primitive is an engineering decision: correctness first, then contention, then complexity.
The three primitives
- Mutex โ one holder at a time. The default choice. Cheap when uncontended (musl: a single CAS in the fast path), expensive under contention.
- Reader/writer lock โ many readers OR one writer. Wins only when reads vastly outnumber writes and the critical section is long enough to matter; otherwise its bookkeeping loses to a plain mutex.
- Condition variable โ lets a thread sleep until state changes. Always paired with a mutex, always waited on in a loop:
pthread_mutex_lock(&mtx);
while (!ready) { /* while, not if */
pthread_cond_wait(&cv, &mtx);
}
pthread_mutex_unlock(&mtx);
The while is not style: pthread_cond_wait may return without anyone signaling (a spurious wakeup is allowed by POSIX), and another thread may consume the condition between signal and wake. The loop re-checks the predicate under the lock.
Barriers
pthread_barrier_wait lets N threads meet at a phase boundary; exactly one caller receives PTHREAD_BARRIER_SERIAL_THREAD. Phases are how parallel algorithms express "nobody proceeds until everyone arrived".
What they cost
Every lock serializes something. The discipline this module drills: keep critical sections small, hold locks across no I/O, and measure contention before reaching for anything fancier.
โก Now practice
Ready to CodeSynchronization DrillsMutexed accounts, condvar queues, rwlock metrics, lock-order diagnosis, and a deterministic pool core.
4 challenges ยท ยท ~22 min