A critical section is code that may run concurrently and accesses shared data or a resource. Like a printer that should finish one file before starting another, it needs protection from conflicting access. section 8.3
Protect shared data by synchronizing the code that uses it:
- Use a mutex to guard operations such as reading or changing a bank balance; a thread that cannot acquire the lock waits until it is released. section 8.4
- Make every thread use the same mutex for that resource. Inconsistent protection can leave the resource exposed to errors. section 8.4
- Synchronization has a cost, so avoiding shared-resource access can sometimes avoid the need for it. section 8.7
# Chapter 8/race_condition/synced_bank_account.py
from threading import Lock
from unsynced_bank_account import UnsyncedBankAccount
class SyncedBankAccount(UnsyncedBankAccount):
def __init__(self, balance: float = 0):
super().__init__(balance)
self.mutex = Lock()
def deposit(self, amount: float) -> None:
self.mutex.acquire() #1
super().deposit(amount)
self.mutex.release() #2
def withdraw(self, amount: float) -> None:
self.mutex.acquire() #1
super().withdraw(amount)
self.mutex.release() #2
See a Python bank-account example that acquires a lock around deposit and withdrawal operations. section 8.4
Chopsticks and dumplings
In the dining-philosophers problem, eating is the critical section: a philosopher locks both chopsticks before taking a dumpling, then releases them. section 9.1








