liveBook · Manning

Go memory model

As explained in 100 Go Mistakes and How to Avoid Them

The Go memory model specifies the allowed behavior and ordering of memory operations in Go programs, including the effects of synchronization between goroutines.

The Go memory model defines when a read in one goroutine is guaranteed to occur after a write in another. Its happens-before rules help prevent data races and make output deterministic. section 8.4.2

A common mistake is assuming that starting a goroutine also waits for it to finish. Goroutine creation happens before execution begins, but goroutine exit does not automatically happen before later events. Reading shared state after launching a writer can therefore race. section 8.4.2

Useful synchronization guarantees include:

  • A channel send happens before the corresponding receive completes, so writes before the send can be observed safely after the receive. section 8.4.2
  • Closing a channel happens before a receive that observes the closure, providing a similar ordering relationship. section 8.4.2

Buffered versus unbuffered synchronization

With an unbuffered channel, the send waits for a receive, ordering the write before the later read. With a buffered channel of capacity one, the send may complete without the receiving goroutine running, so the shared access can race. Choose synchronization according to the ordering guarantee required, not merely the presence of a channel.

i := 0
ch := make(chan struct{})
go func() {
    <-ch
    fmt.Println(i)
}()
i++
ch <- struct{}{}
variable increment < channel send < channel receive < variable read

Trace the happens-before chain from the increment through the channel send and receive to the shared read. section 8.4.2

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Defines happens-before guarantees and works through goroutine, channel-send, channel-close, and buffering cases.
Examples
Uses shared increments, channel sends, channel closure, and buffered-versus-unbuffered channel programs.
What it assumes
Assumes familiarity with goroutines and synchronization through atomic operations, mutexes, and channels.
What you can do after
Diagnose data races by tracing synchronization edges and distinguish race-free access from nondeterministic race conditions.
How it connects
Connects data races, race conditions, goroutines, channels, mutexes, atomic operations, and happens-before ordering.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.