英文:
Using new and channel in go
问题
我在一个技术讲座上找到了下面的代码片段,有一点让我有些困惑。
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
}
}
英文:
I found the code snippet below on a tech talk, I am a little bit confused about one thing.
Should table <- new(Ball)
be placed before go player("ping", table)
?
And why do we even need table <- new(Ball)
? I think table := make(chan *Ball)
already creates the channel.
Has this something to do with deadlocks?
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
}
}
答案1
得分: 5
<-
运算符用于将某物放入通道或从中取出。它所在的一侧显示了它是被放入还是被取出。因为通道没有大小,它实际上不能“容纳”任何项,它会使 go
函数阻塞,直到有东西放入通道中。在没有大小的通道上,两侧(插入和移除)都会阻塞,因此如果在没有接收者的情况下尝试插入某物,它会阻塞,直到有接收者存在。在这个特定的代码中,player
函数将其从 table
中移除 <- table
,然后将其放回 table <-
。
至于你关于移动 table <- new(Ball)
的问题。如果你尝试在没有接收者的情况下发送球,主函数会阻塞等待有人接球。没有大小的通道更像是“交接”对象,因为没有涉及存储。如果它是使用缓冲大小创建的,例如 table := make(chan *Ball, 1)
,那么它只会在已经有一个项时阻塞(与之前相同)。因此,如果在 go
函数之前创建了一个缓冲大小为一的通道,并尝试在放入两个球之前将它们放入通道中,它会像之前一样发生死锁。
链接:https://play.golang.org/p/zrN0D8IYnn
英文:
The <-
operator is what places something in the channel, or takes it out. The side it's on shows you if it's being placed in, or taken out. Because the channel doesn't have a size it cannot actually "hold" and item, it makes the go
funcs block until there is something put in the channel. Both sides (insert and remove) block on a channel with no size, so if you try to insert something when there is no receiver, it blocks until there is one. In this specific code, the player
func then removes it <- table
and places it back in table <-
.
As to your question regarding moving table <- new(Ball)
. If you try to send the ball without a receiver, main blocks waiting for something to take the ball. A channel without a size is more like "handing" off objects because there is no storage involved. If, instead, it was created with a buffer size e.g. table := make(chan *Ball, 1)
, then it only blocks (the same as before) when it already has 1 item in it. So if you created it with a buffer of one, but tried to place 2 balls in it before the go
funcs, it would deadlock same as before.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论