A deadlock occurs when multiple execution entities form a cycle of dependencies: each waits for a resource or action that another entity holds up. In multithreaded C, this prevents progress. section 15.3.4
Two threads, two mutexes
Thread A locks M and then waits for N, while thread B locks N and then waits for M. Neither thread can proceed, so execution has failed. section 20.7
// thread A // thread B mtx_lock(&M);..........................mtx_lock(&N); mtx_lock(&N); /*waiting for B */ mtx_lock(&M); /*waiting for A */
The listing makes the dependency cycle visible: each thread owns one mutex while waiting for the other. section 20.7
Reduce deadlock risk with these rules:
- Lock multiple mutexes in the same order in every critical section. section 20.7
- Avoid designs that require several mutexes; using only one mutex per critical section rules out this class of cycle. section 20.7
- Prefer cnd_timedwait over cnd_wait when condition variables are needed, so a wait does not remain unbounded. section 20.7
- Distinguish deadlock from livelock: deadlocked threads remain blocked, whereas livelocked threads repeat control loops without making progress. section 20.7
A roundabout illustrates the same failure: under congestion, every vehicle occupies space needed by another, leaving no route for progress. Proving that a multithreaded program is entirely free of deadlocks is difficult. section 15.3.4














