主要的围棋例程将球放在 channel 上。 player goroutine 拿到球,操纵它,然后将球放回 channel 并循环。此时它停止了。
为什么播放器 goroutine 会停止?它不应该能够从自己身上捡到“球”吗?抱歉,如果这让我眼前一亮,但我对 golang 并发的理解让我相信玩家 go routine 应该能够自己打乒乓球。
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
}
}
最佳答案
它不会停止。
它只是退出。
那是因为玩家在送回 Ball 时,必须等待 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
OP添加 in the comments :
I meant, why doesn't it loop more than once in
player
?
If you increase the sleep time to 10 it becomes more evident
这是一个playground example with main
waiting 10 seconds .
player
不会循环,因为 table
是一个无缓冲 channel :一旦玩家将 Ball 发回,玩家就会阻塞 直到有人把球从 table 上拿走。
并且没有人可以移除所述Ball
:main
正在休眠 10 秒,然后将其移除并立即退出,防止玩家继续循环(因为所有程序已经停止)
请参阅“do Golang channels maintain order”,以查看无缓冲 channel 与缓冲 channel 的图示。
表休眠 10 秒,但是有一个缓冲 channel (容量为 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
即:玩家 1
从 table
中挑选自己的 Ball
,并将其送回 table 。它不会阻塞,因为缓冲 channel 没有重载。
关于go - 为什么这段代码会停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48941261/