在学习golang的过程中,当我试图理解内存模型规范中描述的通道通信时,我有点困惑,如下所示:
- 通道上的发送发生在该通道的相应接收完成之前。
- 通道的关闭发生在接收返回零值之前,因为通道已关闭。
- 来自无缓冲通道的接收发生在该通道上的发送完成之前。
- 容量为 C 的通道上的第 k 次接收发生在该通道的第 k+C 次发送完成之前。
前两条规则清晰易懂,而我对第三条规则感到困惑,这似乎与其他规则相反......我是否错过了无缓冲通道的特别之处?或者我是否正确如果我像下面的规范中的示例一样采用它:
var c = make(chan int)
var a string
func f() {
a = "hello, world"
<-c // A
}
func main() {
go f()
c <- 0 // B
print(a)
}
对于无缓冲通道,发送操作(B)被阻塞,直到接收器准备好接收值(A)?(如:B 开始,直到 A 执行才返回)它准确吗?
我在Effective Go 规范中找到了以下陈述,但与我的理解仍然存在差异......那么有人可以用简单明了的方式解释一下吗?
接收器总是阻塞,直到有数据要接收。如果通道没有缓冲,发送方会阻塞,直到接收方收到该值。如果通道有缓冲区,发送方只会阻塞,直到值被复制到缓冲区;如果缓冲区已满,这意味着要等到某个接收器检索到一个值。