我很惊讶 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 关注
- 196 浏览
添加回答
举报
0/150
提交
取消