liveBook · Manning

Chapter 20: Threads

What you will learn in chapter 20 of Modern C, Third Edition

Introduces threads as concurrent control flows through the B9 game, then shows how C starts, runs, and joins its task threads.

After this chapter you will be able to

What it builds on

Section by section

Introduction

Introduces threads as concurrent control flows through the B9 game, then shows how C starts, runs, and joins its task threads.

Key terms: threads, tasks, control flow, concurrently, <threads.h>, thrd_create, join, main, B9, Draw

20.1 Simple interthread control

This section explains how threads wait for one another and communicate through shared data, why conflicting accesses can cause races, and how atomic objects provide safe operations.

Key terms: thrd_join, finished, shared, non-atomic object, race condition, _Atomic, atomic objects, indivisible, linearizable, _Atomic(T)

20.2 Race-free initialization and destruction

This section explains how to initialize shared objects before concurrent access, use call_once when initialization must happen later, and avoid destroying shared objects while threads may still use them.

Key terms: shared objects, static storage duration, automatic or allocated storage duration, call_once, once_flag, callback function, errlog, FILE*, race-free, fprintf

20.3 Thread-local data

The section explains how to avoid races by keeping thread-specific data separate, using local variables, thread_local variables, or thread-specific storage as appropriate.

Key terms: race conditions, thread-specific data, local variables, thread_local, static storage duration, file scope, thread-specific storage, tss_t, key, tss_dtor_t

20.4 Critical data and critical sections

This section explains how mutexes protect critical data, what their lock operations guarantee, and how to initialize, use, and destroy them correctly.

Key terms: _Atomic, mtx_t, critical data, critical section, mtx_lock, mtx_unlock, linearizability, mtx_init, mtx_plain, mtx_timed

20.5 Communicating through condition variables

This section explains how threads use condition variables, condition checks, and a mutex to wait for work and signal one another safely.

Key terms: condition variable, condition expression, life_wait, cnd_timedwait, L->finished, mtx_t, cnd_wait, cnd_signal, cnd_broadcast, mutex

20.6 More sophisticated thread management

This section explains how to manage threads without relying on a parent-child hierarchy, including letting main end while other threads continue, detaching unjoined threads, and giving up processing time when a thread has no work.

Key terms: thrd_t, main, exit, thrd_exit, L, global variable, atexit handler, thrd_detach, join, detached thread

20.7 Ensure liveness

This section distinguishes deadlock from livelock, gives rules for avoiding blocked waits, and sketches why example B9 continues to make progress or terminates.

Key terms: deadlock, livelock, mutexes, critical sections, same order, cnd_timedwait, cnd_wait, life_wait, mtx, account_thread

20.8 Summary

Where this is used later

Concepts explained in this chapter

← Chapter 19: Variations in control flow Chapter 21: Atomic access and memory consistency →

These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.