liveBook · Manning

Rwlock

As explained in Learn Concurrent Programming with Go

A readers-writer lock is a synchronization lock that permits multiple simultaneous readers while granting writers exclusive access.

A readers-writer lock protects shared data while permitting concurrency that a plain mutex would block. Any number of goroutines may hold the read side together, but a writer needs exclusive access: while writing, no other reader or writer may enter; while reading, writers wait. This makes the lock useful when updates are rare compared with reads, where serializing every lookup would unnecessarily limit throughput. section 4.0 section 4.2

In Go, `sync.RWMutex` separates the two kinds of critical section:

  • Use `RLock()` before reading shared state and `RUnlock()` after the read-only work. Multiple readers can copy or inspect the same data concurrently. section 4.2.1
  • Use `Lock()` before modifying shared state and `Unlock()` afterward. A write lock blocks every other access, like a normal mutex. section 4.2.1
  • Choose it for read-heavy workloads rather than assuming it improves every concurrent program; ordinary mutexes remain appropriate when broad exclusion is needed. section 4.2 section 4.4

Serving frequent game-update requests

A server keeps match events in a shared slice. One recorder appends an event a few times per second, while thousands of client handlers repeatedly copy the event list. The recorder holds the write lock around `append`; each handler holds the read lock only while copying. Readers can run together, and observed runs finish substantially sooner than the version that gives every handler an exclusive mutex. section 4.2.1

Figure 4.7 Goroutines using a readers–writer lock

Compare the two lock states: read access admits multiple goroutines but excludes writers, whereas write access excludes both readers and writers. section 4.2.1

A simple read-preferred implementation can be built from two ordinary mutexes and a reader counter. A reader briefly locks the counter, increments it, and the first reader locks a global mutex that writers require. On exit, a reader decrements the counter; the last reader releases that global mutex. This preserves concurrent reads while keeping writers out until all active readers leave. section 4.2.2

Read preference has a failure mode: a continuing stream of readers can leave no reader-free interval for a writer. This write starvation prevents an update indefinitely. A write-preferring design addresses it with a condition variable, tracking waiting writers and refusing new readers whenever a writer is waiting or active; readers and writers broadcast when their state changes. section 5.1.4 section 5.1.4

How Learn Concurrent Programming with Go covers it

How deep it goes
Explains API use, benchmarks a server scenario, and builds read- and write-preferring implementations from mutexes and condition variables.
Examples
Demonstrates a basketball-event server with periodic writes and thousands of list-copying client handlers, then simulates writer starvation.
What it assumes
Builds from mutex-protected critical sections and introduces the reader-versus-writer distinction through goroutine access to shared resources.
What you can do after
Build it from scratch with counters and mutexes, and apply Go’s sync.RWMutex to separate read and write critical sections.
How it connects
Connects mutexes, critical sections, race conditions, condition variables, and starvation.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Concurrent Programming with Go. The section links point to the parts of the book it draws on.