Readers–Writers Problem & Semaphore Solution – Study Notes
Chapter 1 – Introduction: Revisiting Classic Synchronisation Problems
• Recap of previous lecture: Bounded‐Buffer/Producer–Consumer problem solved with semaphores.
• Today’s focus: Readers–Writers problem – another classic synchronisation scenario.
• Scenario Definition
– A shared database is concurrently accessed by several processes.
– Two distinct classes of processes:
1. Readers → only perform read (no modification).
2. Writers → perform both read and write (update) operations.
• Key Observations
– Concurrent reads by multiple readers cause no side-effects; i.e. data remain unchanged.
– Any overlap that involves at least one writer (writer + reader, or writer + writer) can corrupt data or yield inconsistent views ("chaos").
– Requirement: Writers must obtain exclusive access to the database when modifying.
• Why classified as a synchronisation problem?
– We must coordinate concurrent processes so that safety (no simultaneous conflicting access) and liveness (everyone eventually proceeds) are upheld.
Chapter 2 – Problem Restatement & Synchronisation Goals
• Formal statement: "Allow multiple readers to read simultaneously unless a writer is writing. Only one writer may write at a time, and writers must not write while any reader is active."
• Variants
– Reader-priority, Writer-priority, Fair (no starvation). Current lecture uses reader-priority implementation.
• General Rules enforced:
Readers may share the database with other readers.
A Writer requires exclusive (mutual-exclusion) access.
• Solution Ingredients
– Two binary semaphores.
– One ordinary integer variable.
\text{mutex}
Initial value = 1.
Purpose : Protect the critical section in which \text{readCount} is updated (ensures atomicity of increment/decrement operations).\text{WRT} (pronounced "write")
Initial value = 1.
Shared by both readers and writers; provides mutual exclusion for actual database access by writers (and by first/last reader, as we shall see).\text{readCount} (integer)
Initial value = 0.
Tracks the current number of readers inside the critical section.
• Remember: \text{mutex} and \text{WRT} are semaphores (binary), whereas \text{readCount} is a plain variable.
Chapter 3 – Writer Algorithm Walk-through
Pseudo-code skeleton (reader-priority flavour):
do {
wait(WRT); // request exclusive access
/* critical section: perform WRITE */
signal(WRT); // release exclusive access
/* remainder section */
} while (true);
Explanation & Trace
wait(WRT) – If no other reader/writer holds \text{WRT} the writer enters, else it blocks.
In the critical section the writer updates the database.
signal(WRT) – Releases the semaphore; now either another writer or readers may acquire it.
Key property: During ownership of \text{WRT}, all other entities (writers or first/last reader) are excluded, guaranteeing single-writer safety.
Chapter 4 – Reader Algorithm Walk-through
Pseudo-code skeleton:
do {
/* Entry section */
wait(mutex);
readCount++;
if (readCount == 1)
wait(WRT); // first reader locks writers out
signal(mutex);
/* critical section: perform READ */
/* Exit section */
wait(mutex);
readCount--;
if (readCount == 0)
signal(WRT); // last reader unlocks writers
signal(mutex);
/* remainder section */
} while (true);
Detailed Explanation
Entry – locking \text{mutex} ensures modifications of \text{readCount} are atomic.
Increment \text{readCount}; the arriving reader announces its presence.
First Reader Rule – If \text{readCount} = 1, this is the first active reader, so it performs wait(WRT).
– Consequence: Writers are blocked while any reader is present.signal(mutex) – Releases protection so further readers may concurrently modify \text{readCount} (one at a time) and proceed.
Critical Section – Reader accesses database concurrently with other readers.
Exit — wait(mutex) again to safely decrement \text{readCount}.
Last Reader Rule – When \text{readCount} = 0 after decrement, the last reader performs signal(WRT), re-enabling writers.
Release \text{mutex}.
Concurrency Insight
• Multiple readers may be inside simultaneously because after first reader released \text{mutex}, further readers can fast-path into the DB.
• Writers must wait until all readers exit because \text{WRT} remains held until \text{readCount} drops to 0.
Chapter 5 – Correctness Arguments & Properties
Safety Conditions Satisfied
Mutual exclusion for writers – \text{WRT} is binary; only one writer can hold it at a time.
No reader–writer overlap – First reader locks \text{WRT}; writers cannot proceed while readers present.
Readers can coexist – \text{WRT} is not re-acquired by subsequent readers; only \text{mutex} (quick) is used, allowing parallel reads.
Progress & Priority
• Reader-priority: If readers continually arrive, writers may starve (because \text{readCount} may never become zero). Alternative variants adjust to give writers priority or fairness.
Deadlock Freedom
• Semaphore acquisition ordering is consistent (each reader locks \text{mutex} before possibly \text{WRT}; writer locks only \text{WRT}). No circular wait -> no deadlock.
Chapter 6 – Illustrative Example Trace
Suppose the following timeline:
Reader R1 arrives (readCount = 0).
– Locks \text{mutex}, sets readCount = 1, locks \text{WRT}, releases \text{mutex}.Concurrently, Reader R2 arrives.
– Waits for \text{mutex}, increments readCount = 2, (skip wait(WRT) because not first), releases \text{mutex}.Writer W1 arrives.
– Attempts wait(WRT) but blocks (held by R1).R1 finishes: in exit, locks \text{mutex}, readCount = 1, no signal(WRT)$, releases \text{mutex}.
R2 finishes: exit decrements readCount = 0, signals \text{WRT} (unblocks W1).
W1 enters, performs write, then signals \text{WRT}, permitting next readers/writers.
Data integrity is preserved throughout.
Chapter 7 – Connections & Broader Context
• Relates to critical section problem, mutual exclusion, semaphore primitives introduced earlier.
• Real-world analogies
– Database management systems (locking modes: shared vs. exclusive).
– File systems (read locks vs. write locks).
– Version-control tools (checkout vs. commit).
• System Design Implications
– Need to balance throughput (many readers) against fairness (writers not starving).
– Potential performance bottleneck when read-to-write ratio is extreme.
• Ethical/Practical Considerations
– Incorrect locking can yield data loss, inconsistent user views, financial errors.
– Starvation must be mitigated in production systems to maintain QoS agreements.
Chapter 8 – Key Takeaways & Formulae Recap
Variables & Initialisations
mutex = 1,\qquad WRT = 1,\qquad readCount = 0
Essential Rules Summarised
First reader performs wait(WRT); last reader performs signal(WRT).
Every reader change to readCount is bracketed by wait(mutex) / signal(mutex).
Writer simply performs wait(WRT) / signal(WRT)$$ around its critical section.
Benefits of Semaphore Solution
• Simple, portable.
• Avoids busy waiting when semaphores are blocking primitives.
Limitations
• Reader-priority variant can starve writers.
• Requires careful ordering to avoid deadlock (variant implementations may complicate ordering).
Practice Questions
Modify the algorithm to give writer-priority; what changes to semaphore ordering are needed?
Analyse starvation risk with varying arrival rates of readers/writers; propose mitigation strategies.
End of study notes.