下面是摘自“ Google I/O 2012 - Go Concurrency Patterns ”(幻燈片)的代碼示例package mainimport ( "fmt" "time")func main() { joe := boring("Joe") ann := boring("Ann") for i := 0; i < 5; i++ { fmt.Println(<-joe) fmt.Println(<-ann) } fmt.Println("The end")}func boring(msg string) <-chan string { c := make(chan string) go func() { for i := 0; ; i++ { c <- fmt.Sprintf("%s %d", msg, i) time.Sleep(time.Second) } }() return c}輸出:Joe 0Ann 0Joe 1Ann 1Joe 2Ann 2Joe 3Ann 3Joe 4Ann 4The end這是演講者 Rob Pike 的解釋(視頻中的 16:33):“...我們正在讀取 Joe 的值和 Ann 的值。而且由于頻道的同步性質,兩個人輪流進行,不僅打印出值,還執行它們。因為如果 Ann 準備發送值但 Joe 還沒有這樣做,Ann 仍然會被阻塞,等待將值傳遞給 main。 ”這讓我很困惑?!叭绻?Ann 準備發送值但 Joe 還沒有這樣做,Ann 仍將被阻止”是什么意思?正如我們所知,通道在兩個 goroutine 之間建立通信并同步它們的執行。但是我們在這里創建了兩個頻道(joe和ann)。主協程分別通過joe和與兩個新的協程對話ann。這是否意味著通道之間的同步性質也有效?或者主 goroutine 一次只能與一個其他 goroutine 通信?
3 回答

嗶嗶one
TA貢獻1854條經驗 獲得超8個贊
這只是意味著這些通道是無緩沖的。
????fmt.Println(<-joe) ????fmt.Println(<-ann)
在第一行完成之前,第二行將無法執行。
第一個不會完成,直到有東西寫入 joe 的頻道。
如果該頻道已有值,則 Ann 將無法在 Ann 的頻道中寫入。
并且在首先讀取fmt.Println(<-ann)
joe 的頻道(?) 之前,不會讀取該頻道(?fmt.Println(<-joe)
)。
兩個通道都是獨立的(彼此不知道),但讀取操作的順序性質使一個通道等待另一個首先被讀取。

繁星coding
TA貢獻1797條經驗 獲得超4個贊
當您說“一個通道在兩個 goroutine 之間建立通信并同步它們的執行”時,您對情況的描述是錯誤的。
正在發生的同步在通道內。當您嘗試從通道讀取數據時,讀取操作將被阻止,直到數據寫入通道。
在這個例子中有兩個不同的頻道,他們中的任何一個都不知道另一個。重要的細節是此行阻塞,直到數據寫入joe
通道:
fmt.Println(<-joe)
這就是在打印“Joe”之前阻止執行以下行的原因

森林海
TA貢獻2011條經驗 獲得超2個贊
通道是無緩沖的。
c := make(chan string)
容量(以元素數為單位)設置通道中緩沖區的大小。如果容量為零或不存在,則通道沒有緩沖,只有當發送方和接收方都準備好時,通信才能成功。否則,如果緩沖區未滿(發送)或非空(接收),則通道被緩沖并且通信成功而不會阻塞。一個 nil 通道永遠不會準備好進行通信。
接收將按順序,joe 其次是 ann。
fmt.Println(<-joe) fmt.Println(<-ann)
- 3 回答
- 0 關注
- 221 瀏覽
添加回答
舉報
0/150
提交
取消