gpt4 book ai didi

go - 转到股票行情示例未选择 'done'情况?

转载 作者:行者123 更新时间:2023-12-01 21:24:02 25 4
gpt4 key购买 nike

我已将示例https://gobyexample.com/tickers修改为以下脚本:

package main

import (
"fmt"
"time"
)

func main() {
ticker := time.NewTicker(500 * time.Millisecond)
done := make(chan bool)

go func() {
for {
select {
case <-done:
fmt.Println("Received 'done'")
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}()

time.Sleep(1600 * time.Millisecond)
// ticker.Stop()
done <- true
// fmt.Println("Ticker stopped.")
}

与引用的示例的两个区别是,我已注释掉 ticker.Stop()行,并在 fmt.Println("Received 'done'")块中添加了 case <-done行。如果运行此命令,则会观察到以下输出:
> go run tickers.go
Tick at 2019-10-06 15:25:50.576798 -0700 PDT m=+0.504913907
Tick at 2019-10-06 15:25:51.074993 -0700 PDT m=+1.003102855
Tick at 2019-10-06 15:25:51.576418 -0700 PDT m=+1.504521538

我的问题:为什么不将 Received 'done'打印到终端?

奇怪的是,如果我在 Ticker stopped Println语句中发表评论,我也会看到 Received 'done':
> go run tickers.go
Tick at 2019-10-06 15:27:30.735163 -0700 PDT m=+0.504666656
Tick at 2019-10-06 15:27:31.234076 -0700 PDT m=+1.003573649
Tick at 2019-10-06 15:27:31.735342 -0700 PDT m=+1.504833296
Ticker stopped.
Received 'done'

我记得,可以假定Goroutine中的代码是同步运行的,所以我感到困惑的是,在前一种情况下,我看不到 Println语句的影响,因为它发生在Goroutine返回之前。有人可以解释吗?

最佳答案

... why does it not print Received 'done' to the terminal?



它确实可以,或者,它会尝试。

当主goroutine(称为 main包的 main)返回(或更早在各种情况下未在此处发生)时,Go程序退出。调用 main然后在 time.Sleep()上发送 true后,您的 done返回。

同时,当 for值到达 true channel 时,位于 done循环中的goroutine会唤醒。这在主goroutine发送完之后发生,此后主goroutine正在退出过程中。

如果在退出过程中主goroutine花费了足够长的时间,则匿名goroutine将有时间打印 Received 'done'。如果在退出过程中主goroutine足够快,则匿名goroutine永远不会完成,甚至可能永远不会开始,打印任何内容,而您什么也看不到。 (实际输出是通过单个基础系统调用完成的,因此您可以全部获得,也可以全部不获得。)

您可以通过多种方法确保在退出主程序之前就完成了goroutine,但是最简单的方法可能是使用 sync.WaitGroup,因为它是为此目的而设计的。创建一个 WaitGroup ,将其计数器设置为1(向其初始零添加1),然后在退出匿名goroutine的途中调用 Done函数。让主goroutine等待它。

参见 Go Playground example

关于go - 转到股票行情示例未选择 'done'情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58261752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com