我在下面的技术演讲中找到了代码片段,我对一件事情有点困惑。
table <- new(Ball)
之前应go player("ping", table)
放置吗?
为什么我们甚至需要table <- new(Ball)
?我认为table := make(chan *Ball)
已经创建了频道。
这与死锁有关吗?
type Ball struct { hits int }
fun 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(100 * time.Millisecond)
table <- ball
}
}
答案 0 :(得分:5)
<-
运算符是在通道中放置内容或将其取出的内容。它所在的一面显示它是否被放入或取出。因为通道没有大小,它实际上不能“保持”和项目,它会使go
funcs阻塞,直到通道中放置了某些内容。双方(插入和移除)阻塞在没有大小的通道上,因此如果您尝试在没有接收器时插入某些东西,它会阻塞直到有一个接收器。在此特定代码中,player
func会将其<- table
删除并将其放回table <-
。
关于移动table <- new(Ball)
的问题。如果你试图在没有接球手的情况下发球,那么主力球会等待接球。没有大小的通道更像是“处理”对象,因为没有涉及存储。相反,如果它是用缓冲区大小创建的,例如table := make(chan *Ball, 1)
,当它已经有1个项目时,它只会阻塞(与之前相同)。所以如果你用一个缓冲区创建它,但是试图在go
funcs之前放置2个球,它会像以前一样死锁。