Learning golang on the way, I got a little confused when trying to understand the channel communications described in the memory model spec as below:
- A send on a channel happens before the corresponding receive from that channel completes.
- The closing of a channel happens before a receive that returns a zero value because the channel is closed.
- A receive from an unbuffered channel happens before the send on that channel completes.
- The kth receive on a channel with capacity C happens before the k+Cth send from that channel completes.
The first 2 rules are clear and easy to understand, while I really got confused about the 3rd rule, which seems opposite to others... Did I miss anything special about unbuffered channel? Or am I correct If I take it like the below with the example in the spec:
var c = make(chan int)
var a string
func f() {
a = "hello, world"
<-c // A
}
func main() {
go f()
c <- 0 // B
print(a)
}
For an unbuffered channel, the send operation(B) is blocked until the receiver gets ready to receive the value(A)? (like: B starts and does not return until A executes) Is it accurate?
And I find the following statements in Effective Go spec, but there's still discrepancy from my understanding... So can someone please explain this in a simple and straightforward way?
Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.