go - 为什么这段代码会停止?

标签 go concurrency

主要的围棋例程将球放在 channel 上。 player goroutine 拿到球,操纵它,然后将球放回 channel 并循环。此时它停止了。

为什么播放器 goroutine 会停止?它不应该能够从自己身上捡到“球”吗?抱歉,如果这让我眼前一亮,但我对 golang 并发的理解让我相信玩家 go routine 应该能够自己打乒乓球。

type Ball struct{ hits int }


func main() {
    table := make(chan *Ball)
    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
    }
}

最佳答案

它不会停止。
它只是退出。

那是因为玩家在送回 Ball 时,必须等待 main 例程将其捡起。
一旦主例程收到球...它就会退出。
这会中断所有当前的 goroutine,这意味着玩家完成的循环已停止。

actual example在这里...它有两个玩家。

只需添加:

go player("ping", table)

还有你will see (playground) :

ping 1
pong 2
ping 3
pong 4
ping 5
pong 6
ping 7
pong 8
ping 9
pong 10
ping 11
pong 12

OP添加 in the comments :

I meant, why doesn't it loop more than once in player?
If you increase the sleep time to 10 it becomes more evident

这是一个playground example with main waiting 10 seconds .

player 不会循环,因为 table 是一个无缓冲 channel :一旦玩家将 Ball 发回,玩家就会阻塞 直到有人把球从 table 上拿走。
并且没有人可以移除所述Ball:main 正在休眠 10 秒,然后将其移除并立即退出,防止玩家继续循环(因为所有程序已经停止)

请参阅“do Golang channels maintain order”,以查看无缓冲 channel 与缓冲 channel 的图示。

表休眠 10 秒,但是有一个缓冲 channel (容量为 1),here is what you would see (playground) (玩家睡了 1 秒):

pong 1
pong 2
pong 3
pong 4
pong 5
pong 6
pong 7
pong 8
pong 9
pong 10
pong 11
time's up

即:玩家 1table 中挑选自己的 Ball,并将其送回 table 。它不会阻塞,因为缓冲 channel 没有重载。

关于go - 为什么这段代码会停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48941261/

相关文章:

go - 如何在 golang 中构建 .a 文件

arrays - 如何以这种方式分割字符串?

python - Python 中的 set.copy() 是原子的吗?

java - Java中如何并发执行同一个方法

go - 如何使用 fmt.Sscan 将整数解析为数组?

go - 如何从外部杀死正在运行的 goroutine?

templates - 如何从 template.FuncMap 返回 HTML 模板?

ruby - 为什么在没有设置调度程序的情况下顺序运行的 Ruby 纤程在设置调度程序时会同时运行?

Java ThreadPoolExecutor 在一段时间后停止工作

javascript - JavaScript的执行流程可以中断吗?