EmbeddedPathashala — Linux Programming Interface Series
Chapter 30: Thread Synchronization
Mutexes & Condition Variables — Making threads work safely together
10
Topic Files
2
Main Topics
7
Subsections
Free
Always
What Is This Chapter About?
When multiple threads share data, they can step on each other’s work. Imagine two people editing the same Google Doc at the same time without seeing each other’s changes — chaos! The same thing happens in multi-threaded programs.
This chapter teaches you two powerful tools that threads use to coordinate with each other:
- Mutex (Mutual Exclusion Lock) — Only one thread can hold the lock at a time. Others must wait. This protects shared data from being corrupted.
- Condition Variable — A thread can sleep and wait until another thread wakes it up by signaling that something has changed. This avoids wasting CPU in busy loops.
Together, mutexes and condition variables are the foundation of all thread synchronization in Linux C programming.
Key Terms You Will Learn
mutex pthread_mutex_t pthread_mutex_lock pthread_mutex_unlock critical section deadlock mutex hierarchy PTHREAD_MUTEX_INITIALIZER pthread_mutex_init pthread_mutex_destroy mutex types RECURSIVE mutex ERRORCHECK mutex condition variable pthread_cond_t pthread_cond_wait pthread_cond_signal pthread_cond_broadcast spurious wakeup producer-consumer predicate futex
All Topics — Chapter 30
30.1 — The Problem: Shared Variables & Critical Sections
Why threads need synchronization at all
Race Condition Critical Section Atomicity glob increment bug
30.1.1 — Statically Allocated Mutexes
Creating a mutex the simple way using PTHREAD_MUTEX_INITIALIZER
pthread_mutex_t PTHREAD_MUTEX_INITIALIZER Static allocation
30.1.2 — Locking and Unlocking a Mutex
pthread_mutex_lock, unlock, trylock, timedlock
pthread_mutex_lock pthread_mutex_unlock pthread_mutex_trylock pthread_mutex_timedlock EBUSY ETIMEDOUT
30.1.3 — Performance of Mutexes
How much does a mutex actually cost? futex internals
futex System call cost Atomic operations Lock contention
30.1.4 — Mutex Deadlocks
When threads block each other forever — and how to avoid it
Deadlock Lock Hierarchy Try-and-back-off
30.1.5 / 30.1.6 / 30.1.7 — Dynamic Init, Attributes & Mutex Types
pthread_mutex_init, destroy, and mutex type options
pthread_mutex_init pthread_mutex_destroy NORMAL ERRORCHECK RECURSIVE DEFAULT
30.2 / 30.2.1 — Condition Variables Introduction
What problem do condition variables solve? Static allocation
pthread_cond_t PTHREAD_COND_INITIALIZER Busy-wait problem Producer-Consumer
30.2.2 — Signaling and Waiting on Condition Variables
pthread_cond_signal, broadcast, wait, timedwait
pthread_cond_signal pthread_cond_broadcast pthread_cond_wait pthread_cond_timedwait atomic unlock+sleep
30.2.3 — Testing a Condition Variable’s Predicate
Why you must use while loop not if — spurious wakeups explained
Predicate while loop Spurious wakeup Loose predicate
30.2.4 / 30.2.5 — Full Example & Dynamic Condition Variables
Joining any terminated thread + pthread_cond_init/destroy
thread_multijoin TS_ALIVE / TS_TERMINATED pthread_cond_init pthread_cond_destroy
Ready to Start?
Begin with the race condition problem — the foundation of why synchronization matters.
