# The Go Memory Model

The Go memory model specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine.

Within a single goroutine, a read $r$ observes the value written by the most recent write $w$ to $v$. When multiple goroutines access a shared variable $v$, they must use synchronization events to establish happens-before conditions that ensure reads observe the desired writes.

The initialization of variable v with the zero value for v’s type behaves as a write in the memory model.

Reads and writes of values larger than a single machine word behave as multiple machine-word-sized operations in an unspecified order.

If the effects of a goroutine must be observed by another goroutine, use a synchronization mechanism such as a lock or channel communication to establish a relative ordering.

## Defining happens before

• When a package imports another package, the completion of the imported package’s init functions happens before the start of any of the source package’s
• A go statement happens before the goroutine begins execution
• Channels
• Channel close happens before a receive on the closed channel completes
• Buffered channel: Completion of a channel send happens before the corresponding receive (assuming there is one) completes
• Unbuffered channel: Completion of a channel receieve happens before the corresponding send
• All channels: The $k$th receive on a channel with capacity $C$ happens before the $k+C$th send from that channel completes
• For any sync.Mutex or sync.RWMutex variable l and $n < m$, call $n$ of l.Unlock() happens before call $m$ of l.Lock() returns.
• A single call of f() from once.Do(f) happens before (returns) any call of once.Do(f) returns.

## Incorrect Synchronization

In this program:

var a, b int

func f() {
a = 1
b = 2
}

func g() {
print(b)
print(a)
}

func main() {
go f()
g()
}


it can happen that g prints 2 and then 0. More formally:

A read $r$ may observe the value written by a write $w$ that happens concurrently with $r$. Even if this occurs, it does not imply that reads happening after $r$ will observe writes that happened before $w$.