liveBook · Manning

Critical region

As explained in Software Design for Python Programmers

A critical region is a section of concurrent program execution that accesses a shared resource and must be serialized to preserve correct behavior.

A critical region is the part of concurrent execution that accesses a shared resource. If threads enter it without coordination, their operations can interfere and produce a race condition. Protect the region so that its shared resource remains consistent. section 16.2

Guard a critical region with synchronization that matches the access pattern:

  • Use a mutex when only one thread may read or modify the resource at a time. Acquire it before entering and release it before leaving. section 16.2
  • Use a semaphore when several readers may access a resource simultaneously, while writers must wait until readers finish. section 16.3.1
  • Use a condition object when threads must wait for queue state, such as space becoming available or an empty queue becoming nonempty. section 16.4
  • Release every mutex or semaphore before leaving the region; failing to do so can block other threads indefinitely and cause deadlock. section 16.6

Serializing a shared print stream

Three threads print different messages one character at a time. Without protection, thread scheduling and interrupted I/O intermix the characters, producing different malformed output on different runs. A Python threading.Lock fixes the design: each thread acquires the lock, prints its complete message, and releases the lock. The critical region is the inner printing loop. Writing `with printing_mutex:` expresses the same ownership boundary while ensuring the lock is released when the block ends. section 16.2.1

Reader-writer and producer-consumer regions

Technician threads update a shared meter, so only one technician may set it and no logger may read it during an update. Logger threads can read concurrently through a semaphore. In a bounded queue, producers wait while the queue is full and consumers wait while it is empty; each notifies waiting threads after changing that state. section 16.3.1 section 16.4.2

Figure 16.3 How a mutex guards a critical region. It allows only one thread at a time to be in its critical region.
A diagram of a thread

AI-generated content may be incorrect.

Shows how a mutex permits only one thread at a time to enter a critical region. section 16.2

How Software Design for Python Programmers covers it

How deep it goes
Explains definition, race-condition failure, mutex protocol, reader-writer access, and condition-based waiting through Python examples.
Examples
Demonstrates shared printing, a reader-writer meter, and a bounded producer-consumer queue.
What it assumes
Assumes threads and shared resources, while introducing race conditions, mutual exclusion, blocking, and thread coordination.
What you can do after
Diagnose race conditions and protect Python shared resources with locks, semaphores, and condition objects.
How it connects
Connects critical regions to shared resources, race conditions, mutexes, semaphores, condition objects, producer-consumer coordination, and deadlocks.

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 Software Design for Python Programmers. The section links point to the parts of the book it draws on.