主要的例行程序将球放在一个通道上。玩家goroutine获得球,操纵它,然后将球放回通道并循环。此时它停滞不前。
为什么玩家会停转?不应该能够拿起"球"从自己?对不起,如果这是正确地盯着我,但我对golang并发的理解让我相信玩家常规应该能够自己打乒乓球。
type Ball struct{ hits int }
func main() {
table := make(chan *Ball)
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(100 * time.Millisecond)
table <- ball
}
}
答案 0 :(得分:4)
它没有停滞。
它只是退出。
这是因为当发回球时,球员必须等待main
例程才能拿起球。
一旦主程序接到球......就会退出
这会中断所有当前的goroutine,这意味着播放器完成的循环已停止。
actual example就在这里......它有两个玩家。
只需添加:
go player("ping", table)
ping 1
pong 2
ping 3
pong 4
ping 5
pong 6
ping 7
pong 8
ping 9
pong 10
ping 11
pong 12
我的意思是,为什么它不会在
player
中循环多次? 如果你将睡眠时间增加到10,那就更明显了
这是playground example with main
waiting 10 seconds。
player
不会循环,因为table
是无缓冲的频道:一旦玩家将球发回,玩家阻止,直到任何人移除桌子上的球。
并且没有人可以删除所说Ball
:main
正在睡10秒,然后将其删除并立即退出,阻止玩家再循环一次(因为全部程序已停止)
请参阅“do Golang channels maintain order”,以查看无缓冲与缓冲频道的说明。
桌子休息10秒,但带有缓冲频道(容量为1),here is what you would see (playground)(播放器休眠1秒):
pong 1
pong 2
pong 3
pong 4
pong 5
pong 6
pong 7
pong 8
pong 9
pong 10
pong 11
time's up
即:player 1
从Ball
中选择table
,并将其发回表格。它不会阻塞,因为缓冲的通道不会过载。