Mutual exclusion protects a shared resource by allowing only one thread at a time into its critical region. A mutex enforces this constraint: a thread acquires the lock before accessing the resource, blocks if another thread holds it, and releases it when leaving. section 16.2 section 16.6
Protecting a shared print stream
Three threads print different messages one character at a time. Without a mutex, their output becomes intermingled and varies between runs because thread scheduling and I/O interruptions change the execution order. Adding a threading.Lock around the printing loop makes each complete message print without interference. Python's context-manager form, with printing_mutex:, releases the lock automatically when the protected block ends. section 16.2.1
Apply mutual exclusion by following the protected-resource boundary:
- Identify the shared resource and the statements that read or modify it; those statements form its critical region. section 16.2
- Guard every access to that resource with the same mutex, acquiring it before entry and releasing it before exit. section 16.2 section 16.6
- Keep the protected operation deliberate: locks impose context-switching and synchronization costs, and failing to release one can cause deadlock. section 16.5 section 16.6
- Use a semaphore when several readers may proceed together while writers must be excluded, rather than forcing all readers through one mutex. section 16.3.1 section 16.6
Figure 16.1 A multithreaded application with three threads. The threads share the application’s internal resources of code and data in memory and external resources such as printers and files. The runtime system gives each thread its own runtime stack and the appearance of having its own set of machine registers.
Use the shared-resource diagram to distinguish each thread's private execution state from shared code, memory, files, and printers that may require protection. section 16.1

















