Roy*_*ing 3 channel memory-model go happens-before
在学习golang的过程中,当我试图理解内存模型规范中描述的通道通信时,我有点困惑,如下所示:
- 通道上的发送在该通道的相应接收完成之前发生.
- 关闭通道发生在返回零值的接收之前,因为通道已关闭.
- 来自无缓冲通道的接收在该通道上的发送完成之前发生.
- 具有容量C的信道上的第k个接收发生在从该信道发送的第k + Cth个完成之前.
前两条规则清晰且易于理解,而我对第三条规则感到困惑,这似乎与其他规则相反......我是否错过了任何关于无缓冲通道的特殊规定?或者我是否正确如果我像下面的规范中的示例那样:
var c = make(chan int)
var a string
func f() {
a = "hello, world"
<-c // A
}
func main() {
go f()
c <- 0 // B
print(a)
}
Run Code Online (Sandbox Code Playgroud)
对于无缓冲通道,发送操作(B)被阻塞,直到接收器准备好接收值(A)?(比如:B开始并且直到A执行才返回)它准确吗?
我在Effective Go规范中找到了以下陈述,但是我的理解仍然存在差异......那么有人可以用简单直接的方式解释这个吗?
接收器始终阻塞,直到有数据要接收.如果通道未缓冲,则发送方将阻塞,直到接收方收到该值.如果通道有缓冲区,则发送方仅阻塞,直到将值复制到缓冲区为止; 如果缓冲区已满,则表示等待某个接收方检索到某个值.
您突出显示的句子是您正在寻找的简单解释.
如果通道未缓冲,则发送方将阻塞,直到接收方收到该值.
这是说点3的另一种方式:
来自无缓冲通道的接收在该通道上的发送完成之前发生.
当您发送无缓冲信道时,发送方将阻塞,直到接收方获取该值.这意味着接收在发送完成之前发生.
缓冲的通道是不同的,因为值已经到了某个地方.如果你仍然感到困惑,一个例子可能会有所帮助:
说我想在你家里留一个包裹:
对于无缓冲通道,发送操作(B)被阻塞,直到接收器准备好接收值(A)?(比如:B开始并且直到A执行才返回)它准确吗?
是.这是对的.