liveBook · Manning

Synchronization

As explained in Modern C

Synchronization is the coordination of concurrent execution so that specified operations or events have defined ordering and visibility relationships.

Synchronization coordinates concurrent execution by establishing ordering and visibility between operations. In C, library synchronization functions form release/acquire pairs: a release makes preceding effects available to a corresponding acquire. The resulting relationships, together with atomic operations, establish the happens-before relation used to reason about different threads. section 19.2 section 19.5

TAKEAWAY: The operation that acquires synchronization determines which earlier effects become visible.

  • Thread creation and joining provide ordering around thread entry, termination, and thrd_join; after joining the last thread, its effects are visible to the joining thread. section 19.2
  • call_once makes the first successful initialization call a release for later calls using the same object, so initialized state becomes visible to them. section 19.2
  • Mutex release and acquisition synchronize critical sections; detached threads lose ordinary join-based synchronization and retain only limited termination-handler relationships. section 19.2
  • Sequential consistency is the default model for atomic objects, whereas C library synchronization does not automatically receive that stronger guarantee. section 19.5

One-time error-log initialization

Several threads may reach the same call_once operation concurrently. Exactly one executes errlog_fopen; every caller returning from call_once can use errlog because the initialization effects are visible through synchronization. section 19.2

Table 19.1. C library functions that form synchronization pairs (view table figure)

Release

Acquire

thrd_create(.., f, x) Entry to f(x)
thrd_exit by thread id or return from f Start of tss_t destructors for id
End of tss_t destructors for id thrd_join(id) or atexit/at_quick_exit handlers
call_once(&obj, g), first call call_once(&obj, h), all subsequent calls
Mutex release Mutex acquisition

Maps C release operations to their corresponding acquire operations, including thread lifecycle, call_once, and mutex synchronization. section 19.2

How Modern C covers it

How deep it goes
Explains release/acquire pairs, transitive visibility, call_once, mutexes, and happens-before reasoning.
Examples
Uses thread creation and joining, detached threads, one-time error-log initialization, and mutex-protected critical sections.
What it assumes
Assumes concurrent threads and atomic-access context while defining release/acquire relationships and visibility rules.
What you can do after
Diagnose/debug with it, reason about cross-thread visibility and ordering through happens-before and synchronization pairs.
How it connects
Connects atomic objects, mutexes, call_once, thread creation, thread joining, thread termination, and sequential consistency.

Also explained in

Compare how 11 books explain synchronization →

Related concepts

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