liveBook · Manning

Reader-writer problem

As explained in Grokking Concurrency

The readers-writer pattern coordinates concurrent access so multiple readers can share a resource while writers receive exclusive access.

Imagine a library catalog. Many users can read it together, but librarians must update it alone. The reader-writer pattern applies this idea to shared data: readers may proceed concurrently, while writers receive exclusive access. section 9.9

The coordination rules are simple:

  • Allow any number of readers to access unchanged shared data simultaneously. section 9.9
  • Allow only one writer at a time. section 9.9
  • Block all readers while a writer updates the data. section 9.9
# Chapter 9/reader_writer/rwlock.py
from threading import Lock

class RWLock:
    def __init__(self) -> None:
        self.readers = 0
        self.read_lock = Lock()
        self.write_lock = Lock()

    def acquire_read(self) -> None:             #1
        self.read_lock.acquire()                #1
        self.readers += 1                       #1
        if self.readers == 1:                   #1
            self.write_lock.acquire()           #1
        self.read_lock.release()                #1

    def release_read(self) -> None:             #2
        assert self.readers >= 1                #2
        self.read_lock.acquire()                #2
        self.readers -= 1                       #2
        if self.readers == 0:                   #2
            self.write_lock.release()           #2
        self.read_lock.release()                #2

    def acquire_write(self) -> None:            #3
        self.write_lock.acquire()               #3

    def release_write(self) -> None:            #4
        self.write_lock.release()               #4

The Python implementation counts active readers, protects that count with one lock, and uses another lock to exclude writers while readers are present. section 9.9

Users and librarians

Several User threads can print the same counter value together. A Librarian thread waits for readers, increments the counter, and then releases the write lock. This avoids conflicting read/write and write/write interleavings while avoiding unnecessary serialization of readers. section 9.9

How Grokking Concurrency covers it

How deep it goes
Defines the access rules and demonstrates a Python lock implementation, without developing fairness policies.
Examples
Uses a library catalog, Python User and Librarian threads, a shared counter, and sample concurrent output.
What it assumes
Assumes basic concurrency and synchronization knowledge while teaching reader and writer roles from the library-catalog analogy.
What you can do after
Apply it via Python threading by implementing and using an RWLock for shared counters or other read-heavy data.
How it connects
Connects concurrency, shared data, critical sections, race conditions, synchronization, and readers-writer locks.

Also explained in

Compare how 3 books explain reader-writer problem →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Concurrency. The section links point to the parts of the book it draws on.