学习golang,我当试图理解下面的内存模型规范描述的信道通信的有点糊涂了:通道上如何理解golang内存模型中的通道通信规则?在路上
- 一个发送发生之前对应的从通道接收完成。
- 通道的关闭发生在因为通道关闭而返回零值的接收之前。
- 来自无缓冲通道的接收发生在该通道上的发送完成之前。
- 在容量为C的信道上的第k个接收发生在从该信道发送的第k + C个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 spec中发现了以下声明,但我的理解仍然存在差异......所以有人可以用简单直接的方式解释这个吗?
接收器总是阻塞,直到有数据要接收。 如果通道 未缓冲,发送方将阻塞,直到接收方收到值 。如果通道有一个缓冲区,发送方只会阻塞,直到 值被复制到缓冲区;如果缓冲区已满,则表示 等待某个接收方检索到值。
“发生之前” HB有着非常特殊的意义,仅仅是松散与线性时间内的传统“之前”有关。你可以有两个事件'x'和'y',两个关系保持:'x HB y'和'y HB x'。规则1和3一起粗略地说:“在没有缓冲的通道上发送和接收正确的同步和工作就像你期望的一样(不管CPU如何重组你的指令,你的内存缓存多么积极,什么不缓存)。” – Volker
@Volker嗯...仍然困惑为什么'x HB y'和'y HB x'都成立,哈哈。可能,我需要将一个事件'e'分成不同的原子阶段,比如开始,处理和结束,在为了正确理解这个“发生在......之前”的术语......感谢! –
HB并不意味着实际发生的事情早于其他事物,它只是一个方便的助记符。哪些内存操作是可见的,这是一个_model_,而不是现实,HB建立的是同步保证,它说_nothing_关于实际发生的事情 – Volker