令我感到惊讶的是,惯例似乎完全交错......看到这个之后,我开始相信有一些关于内部的缺失信息,我还没有学到.例:
$ go run x.go > output
$ grep ping output | wc -l
404778
$ grep pong output | wc -l
404777
$ cat x.go
package main
import (
"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
}
}
Run Code Online (Sandbox Code Playgroud)
无论你在播放器功能中设置超时(或者将它们全部一起移除),你总是得到#ping == #ping +/- 1.
您正在使用未缓冲的通道,并且您的两个goroutine与它同步.使用非缓冲通道,通道write(table <- ball)只能在某个地方某人完成read(<-table)后才能完成,因此单个goroutine永远无法读取它所写的值.这就是这个例子的重点.