crontab表达式和算法
来源:互联网 发布:单片机开发设计 编辑:程序博客网 时间:2024/05/28 03:02
crontab 表达式 语法
表达式
min hour day month week cmd
crontab表达式描述的是时间集合 */1 * * * *
表示所有的分钟集合(0-59)都会执行
crontab表达式各个栏位范围如下:
字段名是否必须允许的值允许的特定字符分(Minutes) 是0-59* / , -时(Hours)是0-23* / , -日(Day of month)/td>是1-31 * / , – ?月(Month)是1-12 or JAN-DEC* / , -星期(Day of week)否0-6 or SUM-SAT* / , – ?先那分钟(min)这个栏位来说,我们用 int64 的二进制来标记分钟上的集合,从右往左第1位标识0分钟,第2位标记标识1分钟一直到第60位标记第59分钟.
用程序语言描述的话就是 第0分钟用 1<< 0 标识 第1分钟用 1<<1 标记 第59分钟就是 1<< 59。
“/”符号
ok,照上面说的方法 我们如何表示 */1 * * * *
分钟的所有集合呢?其实 “/”的右边表示集合范围,右边表示步长(step), 我们都可以用下面的算法算出他的标识方式
for i := min; i <= max; i += step { bits |= 1 << i}
表示这个栏位最大的集合,上面的表达式
其实就是 1 << 0 | 1 <<1 | 1 <<2 ... 1<< 59
等同于 ^(MaxUint64 << 60)
等于
二进制 ( 111111111111111111111111111111111111111111111111111111111111)
那么同理 */2 * * * *
标识被2整除的集合就是 1<< 0 | 1<< 2 | 1<<4 .. 1<< 58 等于二进制
(010101010101010101010101010101010101010101010101010101010101)
。
补充说明下
crontab 表达式中 ‘/’ 后面的数值是步长(step) 可执行的时刻值可以理解为 范围内除以 步长 余数为 0 的时刻
例如*/7 * * * *
crontab 在 并不是严格的每7分钟执行一次,他的二进制表示方法如下:
000100000010000001000000100000010000001000000100000010000001
从这个表达式中可以看出 /7 * * * 他的执行分钟时刻为0 7 14 21 28 35 42 49 56 下一个执行时间是 下一个小时的 0分钟 (并不是下个小时的1分钟)
“-“符号
“-”表示一个范围 2-9/2 * * * * 这种表达式 就是 2到9分钟 被2整除的所有集合 就是 2 4 6 8 表示为 1<<2 | 1 <<4 |1<< 6 | 1<< 8
同样它的标识方式时
for i := 2; i <= 9; i += 2 { bits |= 1 << i}
“,”符号
“,”表示枚举值 比如表达式 1,5,9 * * * * 他表示的时1分钟,5分钟和9分钟 1<< 1 | 1<< 5 | 1<< 9
“?”符合
“?”只用于 日(Day of month) 和 星期(Day of week),表示不指定值,可以用于代替 *
其它栏位标识方式
分钟的标识方式已经清楚了,其它的四个栏位标识方式和它一样,唯一有差别的时 栏位的集合范围,比如 分钟是 0-59 小时是 0-23
完整表达式 “1-9/2 8-23 1,3,5 9 ?”
最后这个表达式的标识方式如下:
min : 1010101010 hour : 111111111111111100000000 day : 101010 month : 1000000000 week : 1111111
时间排序和计算下次执行的时刻
step 1 – 遍历任务计算出每个任务下次执行的时间
首先看一下cron的结构体
type Cron struct { Schedule Schedule //时间集合 Job job // cmd Next time.Time //下次执行时间 Prev time.Time //上次执行时间 }
所以遍历的程序看起来像
for i=0;i<len(cron_list);i++{ cron_list[i].Next = calculation(Schedule);//先跳过calculation 函数,后续会说明 }
step 2 – 对任务进行排序
获取到Next的是之后 我们需要对Cron进行按照Next 从小到大排序(最近要执行的排在最前面)
step 3 – 指定时间执行任务
从排过序的列表中拿到第一个cron 的 Next值,程序阻塞等Next时刻的时候执行(当然 需要拿到列表中相同Next的任务 并发执行 而且不能阻塞主进程)
主程序继续对任务列表计算Next值 重复 上面3个步骤。
ok,到了这边 主线流程逐渐清晰了。还剩下 calculation 这个函数的实现没说明,继续外下看。
calculation 函数实现
calculation 计算的是cron时间集合中最近要执行的时刻,那么如何具体如何计算的,
在cron 时间集合里头的 month 里头找到离当前时间最近的月份,然后离当前时间最近的天,然后离当前时间最近的小时 然后离当前时间最近的分钟 是不是就可以了
ok 按照这个思路 程序看起来是这个样子
t = time.Now() while( 1 << t.month() & Schedule.month == 0){ t.month = t.month +1 // 当前时间月份加1 } #day 栏位比较特别 week实际上也是作用于天的,day 表示的是月份的天,所以对天数加的+1的时候 需要同时匹配day 和 week 所以程序 while (!(1<<t.Day() &s.Dom && 1<<t.Weekday() &s.Dow )) { t.Day = t.Day +1 }
下面hour min 类似,最后通过各种+ 操作的 t 就是这个job最近的时刻了。
- crontab表达式和算法
- crontab表达式
- crontab表达式
- 常用crontab表达式整理
- Crontab表达式介绍
- crontab的@reboot表达式
- 正则表达式和算法
- crontab表达式执行时间计算,crontab在线测试
- 算法之中缀表达式和后缀表达式
- 算法之中缀表达式和后缀表达式
- crontab相关命令及表达式
- crontab时间格式表达式说明
- Javascript判断Crontab表达式是否合法
- Crontab重启和crontab -e位置
- /etc/crontab和crontab -e的区别
- /etc/crontab和crontab -e的区别
- samba和crontab
- at 和crontab
- 在Spark中尽量少使用GroupByKey函数
- VMware Ubuntu虚拟机无法进入Unity模式的解决方法
- Java设计模式 单例模式(Singleton)
- 15HD_OJ——今年暑假不AC
- 为什么匿名内部类调用的方法内局部变量必须为final
- crontab表达式和算法
- socket链接
- ubuntu 下从一个python文件中调用另外的一个python文件中的类!
- mysql 5.6 主从复制配制
- 内联函数和预处理宏区别
- thrift TProcessor
- php中ksort和krsort排序问题
- UItableview上自定义cell,带有textview,控制uitableview滚动到响应位置,不被键盘挡住
- 封装音视频流为RTP包来网络传输