• Go语言web开发---Cronexpr 包实现并发定时任务


    安装Cronexpr包:

    go get -u github.com/gorhill/cronexpr
    

     

    这个包支持七位时间控制

    *(秒) *(分) *(时) *(日) *(月) *(周) *(年)

    栗子:

    每5秒执行一次: */5 * * * * * *

    一个简单的小栗子

    package main
    
    import (
    	"fmt"
    	"github.com/gorhill/cronexpr"
    	"time"
    )
    //* * * * * * *
    //秒 分 时 日 月 周 年
    func main() {
    	var expr *cronexpr.Expression
    	var err error
    	//每5秒执行一次
    	if expr, err = cronexpr.Parse("*/5 * * * * * *");err != nil{
    		fmt.Println("err=", err)
    		return
    	}
    
    	//当前时间
    	now := time.Now()
    	fmt.Println("now=",now)
    	nextTime := expr.Next(now)
    	fmt.Println("nextTime=", nextTime)
    
    	time.AfterFunc(nextTime.Sub(now), func() {
    		fmt.Println("被调用了")
    	})
    
    	time.Sleep(6*time.Second)
    }
    

    输出

    now= 2020-05-03 00:58:48.6350048 +0800 CST m=+0.008000001
    nextTime= 2020-05-03 00:58:50 +0800 CST
    被调用了
    

    注意:这里每5秒也好,每3分钟也好,都不是以现在的时间计时的:

    例如:

    每5秒:假设现在12:00:02,下次执行时间将会是12:00:05,他会从0秒开始累加计算下次时间,而不是现在的秒数

    每3分钟:假设现在12:00:02,下次执行时间将会是12:03:00,他会从0分开始累加计算,并且秒数归零

    一个并发多任务的定时任务小案例

    package main
    
    import (
    	"fmt"
    	"github.com/gorhill/cronexpr"
    	"time"
    )
    
    //代表任务
    type CronJob struct {
    	expr *cronexpr.Expression
    	nextTime time.Time
    }
    
    
    func main() {
    	//创建map,用于存储多个定时任务
    	scheduleTable := make(map[string]*CronJob)
    
    	//当前时间
    	now := time.Now()
    
    	expr, _ := cronexpr.Parse("*/5 * * * * * *")
    	cronJob := &CronJob{
    		expr:expr,
    		nextTime:expr.Next(now),
    	}
    	scheduleTable["job1"] = cronJob
    
    	expr, _ = cronexpr.Parse("*/4 * * * * * *")
    	cronJob = &CronJob{
    		expr:expr,
    		nextTime:expr.Next(now),
    	}
    	scheduleTable["job2"] = cronJob
    
    	go func() {
    		for{
    			now := time.Now()
    			//遍历map,取出每一个定时任务,检查是否过期
    			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 {
    			case <-time.NewTimer(100 * time.Millisecond).C:
    
    			}
    		}
    	}()
    	time.Sleep(100*time.Second)
    }
    

      

  • 相关阅读:
    人脸旋转 《转》
    深度学习如何入门?<知乎>
    openGL-------------别人的博客
    如何实现视频的快进快退功能(转)
    MFC+OpenGL基础绘制<转>
    野蒜
    人脸识别68个点<转>
    cv::circle《转》
    HTML5 Canvas之猜数字游戏
    LIRe 源代码分析 3:基本接口(ImageSearcher)
  • 原文地址:https://www.cnblogs.com/yunweiqiang/p/12820483.html
Copyright © 2020-2023  润新知