Race Conditions and Mutual Exclusion
Conflicting shared-data accesses can produce results that depend on their order. A non-atomic read-change-write sequence can lose an update. Mutual exclusion uses a shared lock to protect the required region; threads contending for that lock may have to wait.
What a learner can do afterwards
- Interleave two increment sequences to produce a lost update
- Place a lock around the smallest region that fixes the race
- Explain why a check followed by an action can be wrong even when both are correct
1 · Read
Use this teaching model: an increment has separate read, change and write steps. Threads can take turns between those steps. The increment is not atomic in this model. Actual languages also offer atomic operations, and their rules for unsynchronized access differ; this trace is not a promise about every language.
A shared balance starts at 10. Two threads each add 5. Both read 10, each calculates 15 locally, then each stores 15. The final balance is 15 instead of 20. One update is lost because the later store replaces the earlier result using the same old value.
A critical section accesses shared data that needs mutual exclusion. A thread can be paused while inside it; holding a lock does not stop context switches. Instead, another thread using the same lock cannot enter the protected operation until the lock is released. Unrelated work can still run.
For the balance update, acquire one shared lock before reading. Read, calculate and store while holding it, then release it. Every conflicting balance update must follow that same rule. Locking only the store is too late: both threads could already have read the same old balance.
For check-then-act, hold the same lock across the check and the action that depends on it. Every participant that can change the checked state must coordinate with that lock. The next thread then checks the updated state, rather than using a result from before another thread's action.
Choose a protected region that covers the full shared-data requirement. Keep unrelated printing or slow work outside when it does not need the lock. Longer lock holding can make contenders wait longer. A smaller region is useful only if it still protects the required relationship; cutting out the read can reintroduce the race.
Use one shared lock for conflicting operations. Protect the full read-change-write or check-and-act region; unrelated work can continue outside it.
Original lesson, questions and study cards on race conditions and mutual exclusion, written for this topic.
2 · Watch
En anglaisTake it off screen
Where it sits
8 questions wait behind this lesson, each with its answer explained. Every answer feeds the sky: stars light as they are learned, and dim when it is time to come back.