登录
首页 >  Golang >  Go问答

在 goroutine 中使用 sleep 是否有更好的替代方法

来源:stackoverflow

时间:2024-04-14 22:36:35 273浏览 收藏

学习Golang要努力,但是不要急!今天的这篇文章《在 goroutine 中使用 sleep 是否有更好的替代方法》将会介绍到等等知识点,如果你想深入学习Golang,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!

问题内容

我想写一个工作人员,每 1 小时执行一次工作。目前我们的系统中还没有 cron,所以不想添加 cron。请求对以下实施提出建议:

func init(){
     go startWorker()
}

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

在 go 例程中使用 sleep 是一个坏主意吗?还是有更好的替代方法来完成此类操作。 dojob() 的工作是从数据库中获取过去一小时内发生的所有故障并进行重试


解决方案


按照您设想的方式使用 time.sleep 存在两个问题,一个主要问题,一个次要问题。

你无法终止 goroutine

goroutine 陷入无限循环,因此除非 dojob 发生恐慌,否则它永远不会终止。您可能应该向它传递一个通道,当 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 资源可以忽略不计,但它使用了一个堆栈,大约有十几 kb 左右。这对您来说可能不是问题,但如果是,并且您的应用程序有主循环,那么您可以将代码和 dowork 调用插入到主循环的主 select 语句中。

终于介绍完啦!小伙伴们,这篇关于《在 goroutine 中使用 sleep 是否有更好的替代方法》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>