學習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