liveBook · Manning

Race condition

As explained in Modern C, Third Edition

A race condition is an execution condition in which the result depends on the relative timing or interleaving of accesses by concurrent or asynchronously executing code.

A race condition occurs when concurrent or asynchronously executing code accesses the same object without protection, so the result depends on timing or interleaving. Signal handlers and threads create this risk; conflicting access to a non-atomic object can make execution fail. section 15.3.2 section 20.1

A shared thread flag

_Atomic(bool) finished;\n\n// Shared state changed by different threads\n// Access through the atomic object\n\nIf one thread sets finished while another reads it, atomic access makes each operation indivisible and linearizable. Without the required protection, even a bool update can be interleaved and produce an undefined program state. section 20.1

TAKEAWAY

  • Treat a write to a non-atomic object that another thread simultaneously reads or writes as an execution failure. section 20.1
  • Use atomic objects to rule out potentially conflicting unprotected accesses and to reason about ordering between threads. section 20.1
  • Distinguish atomic initialization from ordinary atomic operations: concurrent atomic_init calls can still produce a race. section 21.3
  // Parameters that will dynamically be changed by
  // different threads
  _Atomic(size_t) constellations; //< Constellations visited
  _Atomic(size_t) x0;             //< Cursor position, row
  _Atomic(size_t) x1;             //< Cursor position, column
  _Atomic(size_t) frames;         //< FPS for display
  _Atomic(bool)   finished;       //< This game is finished.

Inspect shared game-state members declared with _Atomic, including the termination flag and cursor coordinates. section 20.1

How Modern C, Third Edition covers it

How deep it goes
Defines conflicting access, states its failure rule, and introduces atomic indivisibility and linearizability without developing the full memory model.
Examples
Uses shared thread state, a _Atomic(bool) termination flag, cursor coordinates, and concurrent atomic operations.
What it assumes
Assumes familiarity with C objects and execution, while introducing concurrent threads, signal-handler interference, and atomic qualification.
What you can do after
Diagnose potentially conflicting accesses and avoid them with atomic objects, while treating atomic_init as a special unsynchronized case.
How it connects
Connects race conditions with signal handlers, threads, atomics, unsequenced access, linearizability, and sequential consistency.

Also explained in

Compare how 20 books explain race condition →

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.