我很驚訝 go 例程似乎完美地交錯......看到這個之后,我開始相信有一些關于內部結構的缺失信息,我還沒有了解。例子:$ go run x.go > output$ grep ping output | wc -l404778$ grep pong output | wc -l404777$ cat x.go package mainimport ( "fmt" "time")type Ball struct{ hits int }func main() { table := make(chan *Ball) go player("ping", table) go player("pong", table) table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball}func player(name string, table chan *Ball) { for { ball := <-table ball.hits++ fmt.Println(name, ball.hits) //time.Sleep(1 * time.Millisecond) table <- ball }}無論您在播放器功能中設置超時時間(或將其全部刪除),您總是會得到 #ping == #ping +/- 1。
3 回答

森欄
TA貢獻1810條經驗 獲得超5個贊
您正在使用無緩沖通道,并且您的兩個 goroutine 與其同步。使用非緩沖通道,通道寫入 ( table <- ball
) 只能在某個地方有人完成讀取 ( <-table
) 后才能完成,因此單個 goroutine 永遠無法讀取它正在寫入的值。這就是這個例子的全部意義。

千萬里不及你
TA貢獻1784條經驗 獲得超9個贊
Goroutines 可以為任意數量的玩家完美地交錯:
答案是因為 Go 運行時為接收者持有等待FIFO 隊列(goroutines 準備在特定通道上接收),在我們的例子中,每個玩家在他把球傳到桌子上后就準備好了

30秒到達戰場
TA貢獻1828條經驗 獲得超6個贊
默認情況下GOMAXPROCS設置為 1,因此您會看到此行為。如果您增加 GOMAXPROCS,它將不再具有確定性。
請參閱此答案以獲取示例
編輯@DaveC 不同意,但一個簡單的測試表明并非如此。通道是同步的,但是 goroutine 執行的順序不是。這些是不同的概念。輸入上面的代碼,設置 GOMAXPROCS > 1 并運行...
? tmp export GOMAXPROCS=2
? tmp go run balls.go
ping 1
pong 2
? tmp go run balls.go
pong 1
ping 2
? tmp
正如你在上面看到的,goroutines 的執行順序不是確定性的
- 3 回答
- 0 關注
- 229 瀏覽
添加回答
舉報
0/150
提交
取消