gpt4 book ai didi

go - 有没有更好的选择去使用常规 sleep

转载 作者:行者123 更新时间:2023-12-01 20:26:08 25 4
gpt4 key购买 nike

我想写一个每工作1小时要说一次的 worker 。截至目前,我们的系统中没有Cron,因此不想添加cron。在后续实现中提出建议:

func init(){
go startWorker()
}

func startWorker(){
doJob()
time.Sleep(time.Second * 3600)
}

在日常工作中使用 sleep 是个坏主意,还是有更好的选择来做这样的事情。 doJob()的工作是从数据库中获取最近一个小时内发生的所有故障,然后重试

最佳答案

按照您的设想使用time.Sleep有两个问题,一个主要和一个次要。

您无法终止goroutine

goroutine陷入无限循环,因此,除非doJob出现 panic ,否则它将永远不会终止。您可能应该向它传递一个 channel ,该 channel 在goroutine需要终止时将被关闭:

done := make(chan struct{})
go worker(done)
...
close(done)
...
func worker(done <-chan struct{}){
for {
doJob()
timer := time.NewTimer(time.Hour)
select {
case <-timer.C:
// nothing
case <-done:
timer.Stop()
return
}
}
}

或者,更好的是,使用代码:

func worker(done <-chan struct{}){
ticker := time.NewTicker(time.Hour)
for {
doJob()
select {
case <-ticker.C:
// nothing
case <-done:
ticker.Stop
return
}
}
}

这是使用 defer的好样式:

func worker(done <-chan struct{}){
ticker := time.NewTicker(time.Hour)
defer ticker.Stop()
for {
doJob()
select {
case <-ticker.C:
// nothing
case <-done:
return
}
}
}

你在浪费堆栈

当goroutine使用微不足道的CPU资源时,它使用的堆栈大约为十几千字节。对于您来说,这可能不是问题,但如果是这样,并且如果您的应用程序具有主循环,则可以将代码和 doWork的调用插入到主循环的主 select语句中。

关于go - 有没有更好的选择去使用常规 sleep ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62159498/

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