Golang上的Ticker和Daemon

时间:2014-08-02 01:22:46

标签: unix go daemon daemons

是否可以使用Ticker实现长时间运行的守护程序进程的正常终止?我在here上读到了另一个相关的线程,你应该总是关闭通道以避免内存泄漏,但是如果我在守护进程模式下运行它(假设我使用daemonize来处理守护进程以外的操作golang),在进程终止之前,它没有办法进行任何集体清理。除非我遗漏了什么,否则我在这里问一下,在Golang中是否有替代/更好的方法

func main() {
  ticker := time.NewTicker(Interval)
  workers := make(chan bool, 1)

  for t := range ticker.C {
    select {
      case <- ticker.C:
        log.Println("Scheduled task is triggered.", t)
        go runWorker(workers)
      case <- workers:
        log.Println("Scheduled task is completed.")
        // can't return, it needs to be continue running
    }
  }
}

2 个答案:

答案 0 :(得分:3)

我不确定我是否完全理解您的目标,但您始终可以使用signal.Notify

func main() {
    ticker := time.NewTicker(Interval)
    workers := make(chan bool, 1)
    death := make(chan os.Signal, 1)
    signal.Notify(death, os.Interrupt, os.Kill)

    for {
        select {
        case <-ticker.C:
            log.Println("Scheduled task is triggered.", t)
            go runWorker(workers)
        case <-workers:
            log.Println("Scheduled task is completed.")
            // can't return, it needs to be continue running
        case <- death:
            //do any clean up you need and return
        }
    }
}

答案 1 :(得分:1)

你的主要功能是两次读取自动收报机通道,一次是在打勾之后,然后在继续之前再次打勾,这可能不是你想要的(如果Interval是30分钟,那么你每60分钟只运行一次goroutine)。这将是一个更好的方法:

func main() {
  ticker := time.NewTicker(Interval)
  workers := make(chan bool, 1)

  for {
    select {
      case <- ticker.C:
        log.Println("Scheduled task is triggered.", t)
        go runWorker(workers)
      case <- workers:
        log.Println("Scheduled task is completed.")
        // can't return, it needs to be continue running
    }
  }
}

这将在每个间隔后继续创建goroutine。在循环结束之前,您不需要关闭此通道。如果您的应用程序刚退出,那么您的频道将被安全清理。如果你需要提前停止循环,那么只需确保在退出循环之前调用ticker.Stop()。

如果您只想在一段时间后运行一次goroutine,请使用time.AfterFunc

相关问题