gpt4 book ai didi

go - 先等待 time.AfterFunc 然后开始 time.NewTicker

转载 作者:IT王子 更新时间:2023-10-29 02:18:35 25 4
gpt4 key购买 nike

我正在尝试设置一个每小时整点运行的服务例程。在我看来,这两者中的任何一个都很容易。要在整点运行我的例程,我可以使用 time.AfterFunc(),首先计算整点前的剩余时间。为了每小时运行一次例程,我可以使用 time.NewTicker()

但是,我正在努力弄清楚如何仅在传递给 AfterFunc() 的函数触发后才启动 NewTicker

我的 main() 函数看起来像这样:

func main() {
fmt.Println("starting up")

// Here I'm setting up all kinds of HTTP listeners and gRPC listeners, none
// of which is important, save to mention that the app has more happening
// than just this service routine.

// Calculate duration until next hour and call time.AfterFunc()
// For the purposes of this exercise I'm just using 5 seconds so as not to
// have to wait increments of hours to see the results
time.AfterFunc(time.Second * 5, func() {
fmt.Println("AfterFunc")
})

// Set up a ticker to run every hour. Again, for the purposes of this
// exercise I'm ticking every 2 seconds just to see some results
t := time.NewTicker(time.Second * 2)
defer t.Stop()
go func() {
for now := range t.C {
fmt.Println("Ticker")
}
}()

// Block until termination signal is received
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-osSignals

fmt.Println("exiting gracefully")
}

当然 time.AfterFunc() 是阻塞的,我的 Ticker 的有效负载是故意放在一个 go 例程中的,所以它也不会阻塞。这是为了让我的 HTTP 和 gRPC 监听器可以继续监听,但也允许 main() 末尾的代码块在来自操作系统的终止信号时优雅地退出。但现在明显的缺点是 Ticker 几乎立即启动并在传递给 AfterFunc() 的函数触发之前触发两次(2 秒间隔)。输出如下所示:

Ticker
Ticker
AfterFunc
Ticker
Ticker
Ticker
etc.

我想要的当然是:

AfterFunc
Ticker
Ticker
Ticker
Ticker
Ticker
etc.

以下也不起作用,我不确定为什么。它打印 AfterFunc 但 Ticker 从未触发。

time.AfterFunc(time.Second * 5, func() {
fmt.Println("AfterFunc")

t := time.NewTicker(time.Second * 2)
defer t.Stop()
go func() {
for now := range t.C {
fmt.Println("Ticker")
}
}()
})

最佳答案

The Go Programming Language Specification

Program execution

Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

time.AfterFunc(time.Second * 5, func() {
fmt.Println("AfterFunc")
t := time.NewTicker(time.Second * 2)
defer t.Stop()
go func() {
for now := range t.C {
fmt.Println("Ticker")
}
}()
})

defer t.Stop() 停止自动收报机。

您不是在等待 goroutine 运行。

关于go - 先等待 time.AfterFunc 然后开始 time.NewTicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57543721/

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