【问题标题】:some questions about channel of golang关于golang频道的一些问题
【发布时间】:2020-02-02 23:47:56
【问题描述】:

我正在 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
...

但是,如果我删除播放器的一个 goroutine,例如“pong”:

// go player("pong", table) // remove this line

我只得到一个结果:

Ping 1

我不明白func播放器中有一个for循环,并且'table'通道将Ball输出给ball,在循环结束时,我们将Ball放回通道表。为什么玩家“ping”不能自己玩?

【问题讨论】:

标签: go channel goroutine


【解决方案1】:

通道是无缓冲的,这意味着一个例程必须接收才能完成另一个例程的发送。如果您删除pong 播放器,ping 播放器将被阻止在通道上发送(pong 无法接收),因此它永远不会移动到循环的下一个迭代来接收自己的消息。

如果您要使通道缓冲,如果缓冲区中有空间,则发送将是非阻塞的:table := make(chan *Ball, 1)。这将允许一个球被“保持”在通道的缓冲区中,直到接收器准备好。

【讨论】:

    猜你喜欢
    • 2013-12-05
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2018-05-24
    • 2013-07-07
    • 2013-05-10
    • 2012-03-18
    • 2023-03-09
    相关资源
    最近更新 更多