【问题标题】:Should we stop this kind of Ticker?我们应该停止这种 Ticker 吗?
【发布时间】:2019-02-03 18:37:06
【问题描述】:

我有一个时间记录器,它将在时间间隔内(例如每 5 分钟、10 分钟)执行一个函数。我在 goroutine 中创建了这个时间记录器。我听说这种代码即使应用停止也会泄漏内存。只要应用程序运行,此代码将继续运行。它应该停止吗?如何正确停止它?这是我的实现:

go func() {
    for range time.Tick(5 * time.Minute) {
        ExecuteFunctionA()
    }
}()

这样的时间记录器的正确实现是什么?

【问题讨论】:

    标签: go timer cron goroutine


    【解决方案1】:

    如果“应用停止”,什么都不会泄漏。 warning in the documentation 指的是垃圾收集器一旦创建就无法回收通道(time.Tick() 初始化并返回一个 chan),即使您决定将 break 退出,它也会留在内存中你的for 循环。 根据您在问题中的描述,这对您来说应该不是问题,因为只要应用程序正在运行,您就希望自动收报机运行。但如果您另有决定,您可以使用另一种方式,例如:

    go func() {
      for {
        time.Sleep(time.Duration(5) * time.Minute)
        go ExecuteFunctionA()
        if someConditionIsMet {
          break // nothing leaks in this case
        }
      }
    }()
    

    【讨论】:

    • time.Sleep 不等同于 time.Ticker。如果 ExecuteFunctionA 需要一分钟才能完成,则使用 Sleep 进行一次迭代需要 6 分钟,使用 Ticker 需要 5 分钟:golang.org/pkg/time/#NewTicker
    • 好收获。当然,如果执行时间很长,您可以在单独的 goroutine 中运行 ExecuteFunctionA()。我更新了代码示例。
    • 恕我直言,更新的代码无法解决@Peter 提出的问题。考虑一下,如果一次迭代需要 6 分钟,则有两个 goroutine 将运行 ExecuteFunctionA。可能有一些并发问题会使您的程序陷入混乱。
    • 只需使用time.NewTicker 而不是时间。在中断循环时勾选并调用停止。
    【解决方案2】:

    可以使用信道作为媒介以正确停止自动收报机。 P>

    通常,我做到了如下所示:

    var stopChan chan bool = make(chan bool)
    
    func Stop() {
        stopChan <- true
    }
    
    func Run() {
        go func() {
           ticker := time.NewTicker(5 * time.Minute)
           for {
               select {
                   case <- c.stopChan:
                       ticker.Stop()
                       return
                   case <- ticker.C:
                       ExecuteFunctionA()
               } 
           }
        }()
    }
    

    你可以在你想安全地停止了股票的时候调用Stop功能。 P>

    【讨论】:

    • 考虑使用的上下文。跨度>
    • @ MH-cbon你是什么意思?你能告诉一些示例代码?非常感谢。
    • 为什么不延迟ticker.Stop使用()?跨度>
    • 请注意,ticker.Stop()文档:你应该正确排放通道如图所示文档中:if ticker.Stop() { &lt;-ticker.C } 跨度>
    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    相关资源
    最近更新 更多