golang 定时器
上网查了下相关资料,基本上都介绍的是github.com\robfig\cron这个包来执行定时任务,试了下确实可以执行。但是此包下没有删 除任务的方法,只有暂停的方法(Stop),若要停止之前的任务只执行新定义的任务,除非服务器重启再定义新任务。后来又参考了一下其他人的建议,采用了 github.com\jakecoffman\cron这个包。后者是在前者的基础上做了一定的修改,给每个任务添加的一个新属性Name,然后新添加 一个remove(name)方法,用来删除指定名字的任务,经测试使用后可正常删除任务,只不过之前的计划任务名得新建一个全局变量来存储。
以下先简单介绍下定义时间集合的信息:
| 字段名 | 是否必须 | 允许的值 | 允许的特定字符 |
| 秒(Seconds) | 是 | 0-59 |
* / , -
|
| 分(Minutes) | 是 | 0-59 |
* / , -
|
| 时(Hours) | 是 | 0-23 |
* / , -
|
| 日(Day of month) | 是 | 1-31 |
* / , – ?
|
| 月(Month) | 是 | 1-12 or JAN-DEC |
* / , -
|
| 星期(Day of week) | 否 | 0-6 or SUM-SAT |
* / , – ?
|
注:
1)月(Month)和星期(Day of week)字段的值不区分大小写,如:SUN、Sun 和 sun 是一样的。
2)星期
(Day of week)字段如果没提供,相当于是 *
2、特殊字符说明
1)星号(*)
表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month),表示每个月
回到顶部
2)斜线(/)
表示增长间隔,如第1个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后每隔 15 分钟执行一次(即 3、18、33、48 这些时间点执行),这里也可以表示为:3/15
回到顶部
3)逗号(,)
用于枚举值,如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行
回到顶部
4)连字号(-)
表示一个范围,如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时(包括9和17)
回到顶部
5)问号(?)
只用于 日(Day of month) 和 星期(Day of week),表示不指定值,可以用于代替 *
在beego下使用,我简单的封装一下(代码不是我写的,而且写的很随意,也只保证了可用的程度),自定义package jobs如下:
job.go源码:
- package jobs
- import (
- "github.com/astaxie/beego"
- "github.com/jakecoffman/cron"
- "reflect"
- "runtime/debug"
- "sync"
- "sync/atomic"
- )
- type Job struct {
- Name string
- inner cron.Job
- status uint32
- running sync.Mutex
- }
- const UNNAMED = "(unnamed)"
- func New(job cron.Job) *Job {
- name := reflect.TypeOf(job).Name()
- if name == "Func" {
- name = UNNAMED
- }
- return &Job{
- Name: name,
- inner: job,
- }
- }
- func (j *Job) Status() string {
- if atomic.LoadUint32(&j.status) > 0 {
- return "RUNNING"
- }
- return "IDLE"
- }
- func (j *Job) Run() {
- // If the job panics, just print a stack trace.
- // Don't let the whole process die.
- defer func() {
- if err := recover(); err != nil {
- beego.Error("%v", debug.Stack())
- }
- }()
- if !selfConcurrent {
- j.running.Lock()
- defer j.running.Unlock()
- }
- if workPermits != nil {
- workPermits <- struct{}{}
- defer func() { <-workPermits }()
- }
- atomic.StoreUint32(&j.status, 1)
- defer atomic.StoreUint32(&j.status, 0)
- j.inner.Run()
- }
jobrunner.go源码:
- // A job runner for executing scheduled or ad-hoc tasks asynchronously from HTTP requests.
- //
- // It adds a couple of features on top of the cron package to make it play nicely with Revel:
- // 1. Protection against job panics. (They print to ERROR instead of take down the process)
- // 2. (Optional) Limit on the number of jobs that may run simulatenously, to
- // limit resource consumption.
- // 3. (Optional) Protection against multiple instances of a single job running
- // concurrently. If one execution runs into the next, the next will be queued.
- // 4. Cron expressions may be defined in app.conf and are reusable across jobs.
- // 5. Job status reporting.
- package jobs
- import (
- //"fmt"
- "github.com/jakecoffman/cron"
- "time"
- )
- // Callers can use jobs.Func to wrap a raw func.
- // (Copying the type to this package makes it more visible)
- //
- // For example:
- // jobs.Schedule("cron.frequent", jobs.Func(myFunc))
- type Func func()
- func (r Func) Run() { r() }
- //定时执行任务
- func Schedule(spec string, job cron.Job, name string) error {
- sched := cron.Parse(spec)
- /*if err != nil {
- return err
- }*/
- MainCron.Schedule(sched, New(job), name)
- return nil
- }
- // Run the given job at a fixed interval.
- // The interval provided is the time between the job ending and the job being run again.
- // The time that the job takes to run is not included in the interval.
- func Every(duration time.Duration, job cron.Job, name string) {
- MainCron.Schedule(cron.Every(duration), New(job), name)
- }
- // Run the given job right now.
- func Now(job cron.Job) {
- go New(job).Run()
- }
- // Run the given job once, after the given delay.
- func In(duration time.Duration, job cron.Job) {
- go func() {
- time.Sleep(duration)
- New(job).Run()
- }()
- }
- // 暂停所有任务
- func Stop() {
- MainCron.Stop()
- }
- //清空任务
- func Remove(name string) {
- MainCron.RemoveJob(name)
- }
plugin.go源码:
- package jobs
- import (
- "github.com/jakecoffman/cron"
- )
- const DEFAULT_JOB_POOL_SIZE = 10
- var (
- // Singleton instance of the underlying job scheduler.
- MainCron *cron.Cron
- // This limits the number of jobs allowed to run concurrently.
- workPermits chan struct{}
- // Is a single job allowed to run concurrently with itself?
- selfConcurrent bool
- )
- func init() {
- MainCron = cron.New()
- workPermits = make(chan struct{}, DEFAULT_JOB_POOL_SIZE)
- selfConcurrent = false
- MainCron.Start()
- }
因为是网站执行定时任务,这边我是将任务是否开启的控制权放在前端页面,通过点击按钮访问controller方法,从而启动任务,所以我把任务执行方法放在了controller中。通过如下方式调用:
- import (
- //其他引用包我都省略了
- "hnnaserver/src/jobs"
- )
- type job struct {
- user string
- province int64
- method int64
- count int64
- }
- //任务执行的方法
- func (j *job) Run() {
- //do something....
- }
- func (this *SystemController) AutoDisCus() {
- spec := "0 0 15 * * 1-5"//定义执行时间点 参照上面的说明可知 执行时间为 周一至周五每天15:00:00执行
- //spec := "*/5 * * * * ?" //这是网上一般的例子 即每5s执行一次
- j := &job{user, province, method, count}
- jobs.Schedule(spec, j, taskName) //3个参数分别为 执行时间(规则之间介绍过) 要执行的任务 任务名
- }
若要删除某项任务,则调用remove方法即可,如下:
- jobs.Remove(tasksName)
golang 定时器的更多相关文章
- [Go] golang定时器与redis结合
golang定时器与redis结合,每隔1秒ping一下,每隔20秒llen一下队列的长度 package main import ( "fmt" "time" ...
- Golang定时器断续器
定时器 1.定时器结构 结构定义 type Timer struct { C <-chan Time // 接受定时器事件的通道 r runtimeTimer } type runtimeTim ...
- [Go] golang定时器的使用
golang中的定时器是使用的chanel阻塞来实现的,主要使用到了time包中的内容,如果有多个定时器的channel,为了防止阻塞,可以使用select来获取遍历channel 定时器获取的cha ...
- 一周学会go语言并应用 by王奇疏
<一周学会go语言并应用> by王奇疏 ( 欢迎加入go语言群: 218160862 , 群内有实践) 点击加入 零.安装go语言,配置环境及IDE 这部分内容不多,请参考我的这篇安装环境 ...
- Golang之定时器,recover
滴答滴答……定时器的使用 package main import ( "fmt" "time" ) //定时器的使用 func main() { t := ti ...
- 生产者消费者模式做一个golang的定时器
在主程序启动的时候开一个goroutine作为消费者,用管道连接生产者和消费者,消费者处于无限循环,从管道中获取channel传过来定时event 注意:channel在消费者创建的时候就连通生产者和 ...
- golang 中的定时器(timer),更巧妙的处理timeout
今天看到kite项目中的一段代码,发现挺有意思的. // generateToken returns a JWT token string. Please see the URL for detail ...
- golang的定时器NewTimer、NewTicker使用
package main import ( "fmt" "sync" "time" ) /** *ticker只要定义完成,从此刻开始计时, ...
- [Golang]-7 定时器和打点器
目录 定时器 打点器 After()方法 我们常常需要在未来某个时刻运行 Go 代码,或者在某段时间间隔内重复运行. Go 的内置 定时器 和 打点器 特性让这些很容易实现. 定时器 type Tim ...
随机推荐
- quick-cocos2d-x 接入支付宝(android)(转,待验证)
quick-cocos2d-x 实现在lua里面完成android支付宝的接入 一.支付宝注册是很麻烦的一个过程,本文就不解释了,想了解的去官网看下注册流程.然后下载他们的sdk-WS_SECURE_ ...
- Codeforces Round #337 Vika and Segments
D. Vika and Segments time limit per test: 2 seconds memory limit per test: 256 megabytes input ...
- 周赛-The Number Off of FFF 分类: 比赛 2015-08-02 09:27 3人阅读 评论(0) 收藏
The Number Off of FFF Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- Mysql-学习笔记(==》增删主键建立索引 七)
SHOW FULL COLUMNS FROM teacher; -- 增加删除主键 alterCREATE TABLE tt(t INT);ALTER TABLE tt ADD CONSTRAINT ...
- IDEA -14 注册码生成工具
import java.math.BigInteger; import java.util.Date; import java.util.Random; import java.util.zip.CR ...
- qbxt十一系列三
[题目分析] 这完全是个数学题啊,有些崩溃,上午考试写了两个小时,20分,于是乎 下午改啊改啊 改到10分....如果第二个圆的圆心在第一个圆.....呃 说不清楚 像下面这个图这样,两圆重叠部分中C ...
- MTK+高通方案商
1.德信无线通讯科技有限公司 点击打开链接 2.深圳优美科技
- BZOJ 3514 Codechef MARCH14 GERALD07加强版
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3514 题意:给出一个图m条边.每次询问只加入编号在区间[L,R]之内的边有多少连通 ...
- [CF738D]Sea Battle(贪心)
题目链接:http://codeforces.com/contest/738/problem/D 题意:1*n的格子里有a条长为b的船.有一个人射了k发子弹都没打中船,现在问最少再打多少次一定能保证射 ...
- 5.5.3使用terminfo功能标志
当使用terminfo时,需要做的第一件事就是调用函数setupterm来设置终端类型.这将为当前的终端类型初始化一个TERMINAL结构.然后,你就可以查看当前终端的功能标志并使用他们的功能了. # ...