liveBook · Manning

Critical region

As explained in Modern C, Third Edition

A critical section is a region of execution that accesses shared state under synchronization to prevent conflicting concurrent operations.

Suppose one thread changes a game board while another uses it. The board is an array, so it cannot simply be declared _Atomic. Instead, place operations on the shared board inside a critical section protected by a mtx_t mutex. Smaller shared values that are _Atomic can be accessed without that mutex. section 20.4

Protecting a board update

The input thread acquires L->mtx with mtx_lock before calling life_birth9(L), then releases it with mtx_unlock. mtx_lock blocks until no other thread is inside a critical section protected by that mutex. The protection therefore depends on threads using the same mutex for the shared data. section 20.4

Acquiring a mutex also provides a visibility guarantee: after acquiring it, a thread can rely on operations performed before another thread released that same mutex having taken effect. TAKEAWAY: protect code paths that operate on otherwise unprotected shared data; use _Atomic for suitable small shared data. section 20.4 section 20.8

Protection must not come at the cost of permanently stalled threads:

  • If a critical section needs several mutexes, acquire them in the same order across threads. Opposite orders can leave each thread waiting for a mutex held by the other. section 20.7
  • Condition-variable waits need separate liveness care. Prefer cnd_timedwait over cnd_wait to avoid an indefinite wait. 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 two-thread listing shows why a consistent mutex acquisition order matters: each thread holds the lock the other is waiting to acquire. section 20.7

How Modern C, Third Edition covers it

How deep it goes
Defines mutex-protected access, explains acquisition and visibility, and gives liveness rules without attempting a general treatment of parallel computing.
Examples
Uses a mutex-guarded game-board update and a two-thread, two-mutex deadlock.
What it assumes
Assumes familiarity with threads and shared data while explaining what mutex acquisition and release do.
What you can do after
Apply it via C <threads.h> mutex calls to guard shared data and order acquisitions when several mutexes are needed.
How it connects
Connects critical sections to _Atomic objects, mutexes, linearizability, deadlock, and condition variables.

Also explained in

Compare how 9 books explain critical region →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.