4.1 The Critical Section Problem
When concurrent cooperating processes or threads share mutable state (memory, global variables, file handles), unsynchronized simultaneous access can produce inconsistent, corrupt outcomes β a flaw known as a race condition. The region of code that accesses shared resources is designated the Critical Section.
Figure 4.1: Every process follows this four-part structure to ensure mutually exclusive access to shared variables.
The Three Mandatory Solution Criteria
A mathematically sound solution to the critical-section problem must satisfy three strict requirements:
- Mutual Exclusion: If process $P_i$ is executing in its critical section, no other process can be executing in its critical section on the same shared data.
- Progress: If no process is in its critical section and some processes wish to enter, only those processes not executing in their remainder sections can participate in deciding who enters next. This selection cannot be postponed indefinitely (no livelock/deadlock).
- Bounded Waiting: There must exist a bound or limit on the number of times other processes are allowed to enter their critical sections after a process has registered a request to enter, before that request is granted (prevents indefinite starvation).
4.2 Peterson's Solution
Peterson's Solution is a classic, software-based synchronization algorithm designed for two concurrent processes ($P_0$ and $P_1$). It brilliantly satisfies Mutual Exclusion, Progress, and Bounded Waiting using only two shared variables without requiring dedicated hardware instructions.
Figure 4.2: Each process indicates interest via its flag, politely yields turn to the other, and only proceeds when either the other process is uninterested or it is its turn.
Proof of Correctness
- Mutual Exclusion: For both $P_0$ and $P_1$ to be in their critical sections simultaneously, both
flag[0] == trueandflag[1] == truemust hold, ANDturnmust be both 0 and 1 at the same instant β a mathematical impossibility. - Progress & Bounded Waiting: If $P_1$ is not in its critical section,
flag[1]is false, so $P_0$ enters immediately. If both want to enter, the last value assigned toturndetermines who waits; once the current process exits and sets its flag to false, the waiting process immediately enters.
4.3 Semaphores
A semaphore $S$ is a protected integer synchronization tool introduced by Edsger Dijkstra. Except for initialization, a semaphore is accessed strictly through two standard atomic, indivisible operations: wait(S) (historically $P(S)$) and signal(S) (historically $V(S)$).
Figure 4.3: Binary semaphore mutex guards the buffer from simultaneous writes; counting semaphores empty and full track available slots.
Types of Semaphores
- Binary Semaphore (Mutex): The integer value can only be 0 or 1. Used to guarantee mutual exclusion in critical sections.
- Counting Semaphore: The integer value can span an unrestricted positive range. Used to coordinate access to a finite pool of identical resource instances (e.g. tracking $N$ empty slots).
4.4 Classical Synchronization Problems
Computer science researchers rely on classic synchronization scenarios to test and benchmark new concurrency, locking, and deadlock-freedom primitives. The three most celebrated are Bounded-Buffer, Readers-Writers, and Dining Philosophers.
Figure 4.4: Five philosophers require two adjacent forks to eat. If all simultaneously pick up their left fork, a circular wait deadlock halts the system.
The Three Classical Scenarios
- Bounded-Buffer (ProducerβConsumer) Problem: Producer and consumer share a buffer of size $N$. Producers must block when buffer is full; consumers must block when buffer is empty. Solved with mutex and counting semaphores.
- ReadersβWriters Problem: A database is shared among reader and writer processes. Multiple readers can read simultaneously without interference; writers require exclusive access.
- First Readers-Writers (Reader Priority): No reader is kept waiting unless a writer has already secured permission. Can cause writer starvation.
- Second Readers-Writers (Writer Priority): Once a writer is ready, no new readers may start reading. Can cause reader starvation.
- Dining Philosophers Problem: Models allocation of multiple shared resources among competing processes without deadlock or starvation. Naive symmetric code deadlocks. Standard solutions:
- Allow at most 4 philosophers to sit at the table of 5 chairs simultaneously.
- An asymmetric approach: Odd philosophers pick up left fork then right; even philosophers pick up right fork then left.