Lesson 3 / 25

Share Memory by Communicating

The Go proverb and what it means in practice.

Ownership moves with the message

The Go proverb is: Do not communicate by sharing memory; instead, share memory by communicating. Rather than several goroutines touching one variable under a lock, you pass the value (or a pointer to it) over a channel, and the receiver becomes its owner for a while. Only one goroutine works on the data at a time, so no lock is needed. This is a guideline, not a law: channels are great for transferring ownership, distributing work and signalling events, while a sync.Mutex is often simpler for protecting a small piece of shared state such as a counter or a cache. Pick whichever makes the code easiest to reason about.

A goroutine that owns its state

Only the owner goroutine touches the map; others send requests.

package main

import "fmt"

type incr struct {
	key  string
	done chan int // reply channel carries the new count
}

// counter owns counts; no other goroutine can reach the map.
func counter(reqs <-chan incr) {
	counts := map[string]int{}
	for r := range reqs {
		counts[r.key]++
		r.done <- counts[r.key]
	}
}

func main() {
	reqs := make(chan incr)
	go counter(reqs)

	reply := make(chan int)
	for _, k := range []string{"a", "b", "a"} {
		reqs <- incr{key: k, done: reply}
		fmt.Println(k, <-reply)
	}
	close(reqs) // lets the counter goroutine's range loop end
}

Passing the baton

In a relay race only the runner holding the baton runs with it. Handing over the baton is the communication; nobody needs to agree on who may touch it, because only one person can hold it.

Quick check: When is a sync.Mutex usually the better choice than a channel?

  • Streaming results between pipeline stages
  • Handing work items from producers to consumers
  • Signalling to many goroutines that they should stop
  • Guarding a small piece of shared state, such as a counter or cache map
Answer

Guarding a small piece of shared state, such as a counter or cache map — Channels shine for transferring ownership and signalling; mutexes are simpler for protecting state in place.