[TOC] # 简单例子 安装 ~~~ go get -u github.com/gorhill/cronexpr ~~~ ~~~ import ( "fmt" "github.com/gorhill/cronexpr" "time" ) func main() { var ( expr *cronexpr.Expression err error //当前时间 now time.Time nextTime time.Time ) //crontab 分钟(0-59) ,小时(0-23), 天, 月, 星期几只有5个 //每隔5秒执行一次 //他其实支持到秒的,秒 和 年 7个 if expr, err = cronexpr.Parse("*/5 * * * * * *"); err != nil { fmt.Println(err) return } //当前时间 now = time.Now() //下次调度时间 nextTime = expr.Next(now) fmt.Println(now) fmt.Println(nextTime) //睡眠一会,等待定时器超时 time.AfterFunc(nextTime.Sub(now), func() { fmt.Println("被调度了: ", nextTime) }) for { ; } } ~~~ # 子协程检查任务过期 ~~~ import ( "fmt" "github.com/gorhill/cronexpr" "time" ) //代表一个任务 type CronJob struct { expr *cronexpr.Expression nextTime time.Time //expr.Next(now) 下次调度时间,可以看这个任务是不是到期了 } func main() { //需要有个调度协程,他定时检查所有的cron任务,谁过期了就执行谁 var ( cronJob *CronJob //结构体指针,任务 expr *cronexpr.Expression now time.Time //当前时间 scheduleTable map[string]*CronJob //调度表 key: 任务名字 ) //创建任务表 scheduleTable = make(map[string]*CronJob) //当前时间 now = time.Now() //1. 定义个cronjob, MustParse和Parse相比就是里面必须写正确 expr = cronexpr.MustParse("*/5 * * * * * *") cronJob = &CronJob{ expr: expr, nextTime: expr.Next(now), } //任务1注册到调度表 scheduleTable["job1"] = cronJob //2. 定义个cronjob expr = cronexpr.MustParse("*/5 * * * * * *") cronJob = &CronJob{ expr: expr, nextTime: expr.Next(now), } //任务2注册到调度表 scheduleTable["job2"] = cronJob //启动调度协程 go func() { var ( jobName string cronJob *CronJob now time.Time ) //定时检查下任务调度表 for { now = time.Now() for jobName, cronJob = range scheduleTable { //判断是否过期,下次调度时间早于当前,下次调度时间等于当前时间 if cronJob.nextTime.Before(now) || cronJob.nextTime.Equal(now) { //启动一个协程执行这个任务 go func(jobName string) { fmt.Println("协程---执行任务: ", jobName) }(jobName) //计算下次调度时间 cronJob.nextTime = cronJob.expr.Next(now) fmt.Println(jobName, "下次执行时间: ", cronJob.nextTime) } } select { //定时器睡眠100毫秒,在100毫秒可读,返回 case <- time.NewTimer(100 * time.Millisecond).C: } } }() for { ; } } ~~~