我正在YouTube上观看有关并发模式的视频。 有一个乒乓球示例:
type Ball struct{ hits int }
func main() {
table := make(chan *Ball)
go player("ping", table)
go player("pong", table)
table <- new(Ball)
time.Sleep(1 * time.Second)
<-table
}
func player(name string, table chan *Ball) {
for {
ball := <-table
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
table <- ball
}
}
哪个应该给出结果:
Ping 1
Pong 2
Ping 3
Pong 4
...
但是,如果我删除一个球员的例行程序,例如“ pong”:
// go player("pong", table) // remove this line
我只有一个结果:
Ping 1
我不知道func播放器中有一个for循环,并且'table'频道将Ball传给ball,在循环结束时,我们将Ball放回了频道表。为什么玩家“ ping”不能自己玩?
答案 0 :(得分:5)
该通道是无缓冲的,这意味着一个例程必须接收才能完成另一个例程的发送。如果您删除pong
播放器,则会阻止ping
播放器在频道上发送(pong
不能接收),因此它将永远不会移至循环的下一个迭代收到自己的消息。
如果要缓冲通道,则在缓冲区table := make(chan *Ball, 1)
中如果有空间,则发送将是非阻塞的。这样一来,一个球就可以“保留”在通道的缓冲区中,直到接收器准备就绪为止。