Using new and channel in go

huangapple go评论78阅读模式
英文:

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.

https://play.golang.org/p/zrN0D8IYnn

huangapple
  • 本文由 发表于 2017年4月7日 06:39:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/43266868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定