golang memory model
Note that 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.
1 | var a, b int |
it can happen that g prints 2 and then 0.
A send on a channel happens before the corresponding receive from that channel completes.
1 | var c = make(chan int, 10) |
is guaranteed to print “hello, world”. The write to a happens before the send on c, which happens before the corresponding receive on c completes, which happens before the print.
The closing of a channel happens before a receive that returns a zero value because the channel is closed.
In the previous example, replacing c <- 0
with close(c)
yields a program with the same guaranteed behavior.
A receive from an unbuffered channel happens before the send on that channel completes.
1 | var c = make(chan int) |
is also guaranteed to print “hello, world”. The write to a happens before the receive on c, which happens before the corresponding send on c completes, which happens before the print.
If the channel were buffered (e.g., c = make(chan int, 1)) then the program would not be guaranteed to print “hello, world”. (It might print the empty string, crash, or do something else.)
The kth receive on a channel with capacity C happens before the k+Cth send from that channel completes.
This program starts a goroutine for every entry in the work list, but the goroutines coordinate using the limit channel to ensure that at most three are running work functions at a time.
1 | var limit = make(chan int, 3) |