liveBook · Manning

Critical region

As explained in Python Concurrency with asyncio

A critical section is a region of code that accesses shared state and must not be executed concurrently by multiple execution contexts.

A critical region is code that accesses shared state and must not run concurrently with another execution context. A lock, or mutex, lets one process, thread, or coroutine acquire exclusive access, while others wait until the lock is released. section 6.5.2 section 11.2

Use critical regions to keep shared operations consistent:

  • Acquire a lock before reading or changing shared state, perform the critical work, and release the lock afterward. section 6.5.2
  • Protect a shared counter in multiprocessing or threading so concurrent increments do not produce a race condition. section 6.5.2 section 7.3
  • Use async with for asyncio locks; blocked coroutines suspend while other asynchronous work continues. section 11.2

Two coroutines sharing one lock

Two coroutines attempt to enter the same critical region. The first coroutine acquires the lock and works; the second waits, then enters only after the first releases it. A similar pattern protects a socket lookup while a user disconnects. section 11.2 section 11.0

Listing 11.4 Using an asyncio lock
import asyncio
from asyncio import Lock
from util import delay
 
 
async def a(lock: Lock):
    print('Coroutine a waiting to acquire the lock')
    async with lock:
        print('Coroutine a is in the critical section')
        await delay(2)
    print('Coroutine a released the lock')
async def b(lock: Lock):
    print('Coroutine b waiting to acquire the lock')
    async with lock:
        print('Coroutine b is in the critical section')
        await delay(2)
    print('Coroutine b released the lock')
 
 
async def main():
    lock = Lock()
    await asyncio.gather(a(lock), b(lock))
 
 
asyncio.run(main())

Runnable asyncio example showing shared-lock acquisition, critical-region execution, waiting, and release. section 11.2

How Python Concurrency with asyncio covers it

How deep it goes
Explains lock acquisition, blocking, release, context managers, and event-loop scoping without developing advanced locking concepts.
Examples
Uses shared counters, request-progress reporting, competing coroutines, and socket removal to demonstrate protected operations.
What you can do after
Apply it via Python locks to serialize updates and resource access across processes, threads, and coroutines.
How it connects
Connects critical regions with locks, mutexes, race conditions, shared data, semaphores, events, and conditions.

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 Python Concurrency with asyncio. The section links point to the parts of the book it draws on.