我剛接觸golang。今天測試通道在Golang中的工作方式時,我感到非常困惑。根據(jù)教程:僅當(dāng)緩沖區(qū)已滿時才發(fā)送到緩沖的通道塊。當(dāng)緩沖區(qū)為空時接收塊。我的測試程序如下所示:package mainimport "fmt"func main() { ch := make(chan int, 2) go func(ch chan int) int { for i := 0; i < 10; i++ { fmt.Println("goroutine: GET ", <-ch) } return 1 }(ch) for j := 0; j < 10; j++ { ch <- j fmt.Println("PUT into channel", j) }}我得到這樣的輸出:PUT into channel 0PUT into channel 1goroutine: GET 0goroutine: GET 1goroutine: GET 2PUT into channel 2PUT into channel 3PUT into channel 4PUT into channel 5goroutine: GET 3goroutine: GET 4goroutine: GET 5goroutine: GET 6PUT into channel 6PUT into channel 7PUT into channel 8PUT into channel 9請注意,編號2是從通道中取出的,甚至沒有放入通道中。為什么會這樣?
1 回答

蝴蝶刀刀
TA貢獻(xiàn)1801條經(jīng)驗 獲得超8個贊
沒有。將其放在通道上之后Println("PUT into channel")
會發(fā)生您的情況,這意味著在執(zhí)行該print語句之前,有機(jī)會從通道中讀取它。
示例輸出中的實際執(zhí)行順序類似于以下內(nèi)容:
編寫器例程寫入
2
通道。讀取器例程
2
從通道接收。讀者日常印刷品
goroutine: GET 2
。作家的日常打印
PUT into channel 2
您對通道的讀取和寫入以預(yù)期的順序進(jìn)行,只是您的打印語句使它看起來不正常。
如果您將作者的操作順序更改為:
fmt.Println("PUT into channel", j) ch <- j
您可能會看到輸出更接近您的期望。但是,它不一定完全代表操作順序,因為:
執(zhí)行是并發(fā)的,但對stdout的寫入是同步的
每個函數(shù)調(diào)用和通道發(fā)送/接收都為調(diào)度程序提供了切換的機(jī)會,因此即使使用進(jìn)行運行
GOMAXPROCS=1
,它也可以在打印和通道操作(在讀取器或?qū)懭肫髦校┲g切換goroutines。
TL; DR:在記錄并發(fā)操作時,不要過多地閱讀日志消息的順序。
- 1 回答
- 0 關(guān)注
- 278 瀏覽
添加回答
舉報
0/150
提交
取消