golang 定时器问题

自己写了一个定时采集的模块
代码如下图
conf.Time = 3600 (一小时)

func newTicker(conf model.WebsiteConfig) {
    tick := time.NewTicker(time.Second * time.Duration(conf.Time))
    status := make(chan bool)
    ticker := &model.Ticker{
        Tick:   tick,
        Status: status,
        Config: conf,
        Off:    false,
    }
    // 检测是否存在相同采集列表的进程
    exsit := false
    for k, v := range tickers {
        // 检查该采集id是否存在 若存在先关掉当前任务重新创建
        if v.Config.CollectId == conf.CollectId {
            // 检查该ticker是否已经关闭状态
            if !v.Off { // 如果没有关闭 则先关闭掉
                // 停止计时器
                v.Tick.Stop()
                // 跳出协程
                v.Status <- false
            }
            // 当执行v.Status <- false时,该ticker的任务进程已经退出
            // 这时将新的配置覆盖已经关闭的配置
            tickers[k] = ticker
            exsit = true
            break
        }
    }
    fmt.Println("HERE")
    // 若配置信息不存在则添加进任务中心
    if !exsit {
        // 将新定时器加入定时器集合
        fmt.Println("HERE1")
        tickers = append(tickers, ticker)
    }
    // 每次更新或开启配置都先执行一次采集
    go Co.Start(ticker.Config)
    fmt.Println("HERE2")
    // 然后加入定时任务
    go func() {
        running := true
        for {
            select {
            case <-ticker.Tick.C:
                // 执行采集 !!!!!!!!!!!!!!!!!!!!为什么这个ticker.Tick.C就执行了一次?
                Co.Start(ticker.Config)
            case s := <-ticker.Status:
                // 接收关闭状态
                running = s
            }
            if !running {
                break
            }
        }
    }()
}

为什么ticker.Tick.C只执行了一次? 也就是到一个小时的时候Co.Start执行了 但是两个小时候没有再次执行?

阅读 6.6k
5 个回答

每10秒执行一次

package main

import "time"
import "fmt"
func main(){
        ticker := time.NewTicker(time.Second*time.Duration(10))
        var done = make(chan int)
        go func(){
                for t:=range ticker.C{
                        fmt.Println("im doing some biz")
                        fmt.Println("Tick ar",t)
                }
                done <- 0
        }()
        defer ticker.Stop()
        select{
        case <-done:
                fmt.Println("done")
        }
        fmt.Println("ticker stopped")
}
func DoSomething(){
    tickChan := time.NewTicker(time.Minute * 60).C
    for {
        select {
        case <-tickChan:
            XXXXX()
        }
    }
}

这个就是一个小时执行一次的定时任务,XXXX() 是你要执行的函数
然后 在入口入 go DoSomething() jiukeyi le

定时器网上有很多第三方库啊,不用自己写

func DoSomething(){
    tick := time.NewTicker(time.Minute * 60)
    for {
        <-tick.C
        // Do()
    }
}

这样更简洁

case s := <-ticker.Status:
                // 接收关闭状态
                running = s
            }

这里退出可以直接 return 吧

把多于的代码去掉,调试下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题