Introduction
The critical section problem begins with the same danger seen in race conditions: shared data can break when concurrent execution is not controlled. The first step is to identify the exact code region where shared state is accessed.
A critical section is that protected region of code. Mutual exclusion is the rule that prevents more than one thread or process from entering the critical section at the same time.
Critical Section Problem
The critical section problem asks how multiple threads or processes can safely access shared state without corrupting it. The shared state may be a variable, queue, file, table, buffer, or any resource whose correctness depends on controlled access.
For example, a queue operation may need to check the queue, remove an item, and update the size. If another thread enters in the middle, the queue can become inconsistent.
Synchronization starts by finding the region where shared-state rules can break. Without identifying the critical section correctly, even a lock or semaphore may protect the wrong code.
Critical Section Structure
A standard critical section solution has four parts:
Entry section: The thread requests permission to enter the critical section.
Critical section: The thread accesses or modifies shared state.
Exit section: The thread releases permission so another waiting thread may continue.
Remainder section: The thread runs code that does not need shared-state protection.
Only the truly shared and correctness-sensitive part should be inside the critical section. Normal private work should remain outside so the program does not reduce concurrency unnecessarily.
Critical Section and its Structure
Mutual Exclusion
Mutual exclusion means at most one thread or process can be inside the critical section at a time. If Thread A is already inside, Thread B must wait before entering.
This prevents unsafe simultaneous updates. For example, if two workers modify the internal pointers of the same queue together, the queue structure may break. Mutual exclusion makes the queue update happen one at a time.
Mutual exclusion is the first requirement of the critical section problem, but it is not the only requirement. A complete solution must also handle progress and bounded waiting.
Progress and Bounded Waiting
Progress means the system should not delay entry forever when the critical section is free and some thread wants to enter. If no one is inside the critical section, one of the waiting eligible threads should be allowed to move forward.
Bounded waiting means a thread should not be skipped forever after it asks to enter. Other threads may enter before it, but only within a limited bound. This protects fairness and avoids starvation.
Requirement | Meaning |
|---|---|
Mutual exclusion | At most one thread or process is inside the critical section |
Progress | If the critical section is free, entry should not be postponed forever |
Bounded waiting | A waiting thread should eventually get its turn |
A weak solution may provide mutual exclusion but still make a thread wait endlessly. That is why all three requirements matter.
Mutual Exclusion, Progress and Bounded Waiting
Atomicity and Invariants
Atomicity means a group of operations behaves like one indivisible unit. Other threads should not observe the shared state halfway through a related update.
An invariant is a rule that must remain true for shared state. For a queue, one invariant is that the stored size should match the actual number of elements.
If a thread removes an item but has not yet updated the size, another thread may see an inconsistent state. The critical section protects the full operation that preserves the invariant, not just one isolated line of code.
Common Mistakes
Protecting only writes: Reads may also need protection when they depend on consistent shared state.
Making the section too large: Extra code inside the critical section reduces concurrency and increases waiting.
Making the section too small: Splitting related operations can expose half-updated state.
Locking private data: Data used by only one thread usually does not need synchronization.
Ignoring fairness: Mutual exclusion alone does not guarantee bounded waiting.
The goal is to protect the shared-state rule. Synchronization should be chosen after the critical region is understood.
Summary
A critical section is the code region that accesses shared mutable state and can break under unsafe interleaving. The critical section problem asks how threads or processes can enter that region safely.
Mutual exclusion ensures one-at-a-time entry, progress keeps the system moving, and bounded waiting protects fairness. A good solution preserves shared-state invariants without locking more code than necessary.
Be the first to add a comment.