
Go 程序中使用 robfig/cron 启动定时任务后立即退出,是因为 main 函数执行完毕导致进程终止;只需在启动 cron 后阻塞主线程(如使用 select {}),即可保持程序常驻并按计划执行任务。
go 程序中使用 robfig/cron 启动定时任务后立即退出,是因为 `main` 函数执行完毕导致进程终止;只需在启动 cron 后阻塞主线程(如使用 `select {}`),即可保持程序常驻并按计划执行任务。
在 Go 中使用 github.com/robfig/cron(v2/v3)实现定时任务时,一个常见误区是:调用 c.Start() 仅启动了后台 goroutine 来调度任务,但 main() 函数本身会继续执行并迅速结束——一旦 main 返回,整个进程即退出,所有 goroutine(包括 cron 调度器)都会被强制终止。
以下是最小可运行示例,修复了原代码“打印 Done 后立即退出”的问题:
package main
import (
"fmt"
"github.com/robfig/cron/v3" // 注意:推荐使用 v3 版本(模块化、更稳定)
)
func main() {
c := cron.New()
_, err := c.AddFunc("@every 3m", func() {
fmt.Println("Every 3 min — executed at", time.Now().Format("15:04:05"))
})
if err != nil {
panic(err)
}
c.Start()
fmt.Println("Cron scheduler started. Press Ctrl+C to exit.")
// 阻塞主线程,防止程序退出
select {}
}⚠️ 注意事项:
-
必须添加
select {}(或等效阻塞逻辑):这是核心修复点。select {}是 Go 中最轻量、最标准的永久阻塞方式,使maingoroutine 持续等待,从而维持进程生命周期。 -
使用
cron/v3而非旧版cron:原示例导入的是无版本路径的github.com/robfig/cron,该路径已弃用且不兼容 Go modules。请改用github.com/robfig/cron/v3并确保go.mod中声明对应依赖(go get github.com/robfig/cron/v3)。 -
错误检查不可省略:
AddFunc可能返回解析错误(如非法表达式),应显式处理。 -
优雅关闭(进阶建议):生产环境建议监听
os.Interrupt信号,在退出前调用c.Stop()释放资源:
// 示例:支持 Ctrl+C 安全退出
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
fmt.Println("\nShutting down...")
c.Stop()总结:CRON 任务“不运行”的本质不是调度失败,而是程序过早终止。只要保证 main 不退出,robfig/cron 就能可靠驱动定时逻辑——select {} 是简洁、惯用且零开销的解决方案。

















