是否可以使用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
}
}
}
答案 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