美文网首页
Go定时任务

Go定时任务

作者: echo0x | 来源:发表于2020-06-11 14:51 被阅读0次

1.time.Sleep方法

for {
    time.Sleep(3 * time.Second)
    thisTime := time.Now().Format("2006-01-02 15:04:05")
    fmt.Printf("我在定时执行任务time=%s\n", thisTime)
}

2.time.Tick函数:

t1 := time.Tick(3 * time.Second)
    for {
        select {
        case <-t1:
            thisTime := time.Now().Format("2006-01-02 15:04:05")
            fmt.Printf("t1定时器time=%s\n", thisTime)
        }
    }

3.

var wg sync.WaitGroup
    wg.Add(2)
    //NewTimer 创建一个 Timer,它会在最少过去时间段 d 后到期,向其自身的 C 字段发送当时的时间
    timer1 := time.NewTimer(2 * time.Second)

    //NewTicker 返回一个新的 Ticker,该 Ticker 包含一个通道字段,并会每隔时间段 d 就向该通道发送当时的时间。它会调
    //整时间间隔或者丢弃 tick 信息以适应反应慢的接收者。如果d <= 0会触发panic。关闭该 Ticker 可
    //以释放相关资源。
    ticker1 := time.NewTicker(2 * time.Second)

    go func(t *time.Ticker) {
        defer wg.Done()
        for {
            <-t.C
            fmt.Printf("what is %v", t.C)
            fmt.Println("get ticker1", time.Now().Format("2006-01-02 15:04:05"))
        }
    }(ticker1)

    go func(t *time.Timer) {
        defer wg.Done()
        for {
            <-t.C
            fmt.Println("get timer", time.Now().Format("2006-01-02 15:04:05"))
            //Reset 使 t 重新开始计时,(本方法返回后再)等待时间段 d 过去后到期。如果调用时t
            //还在等待中会返回真;如果 t已经到期或者被停止了会返回假。
            t.Reset(2 * time.Second)
        }
    }(timer1)

    wg.Wait()

Tick,Sleep,包括time.After函数,都使用的timer结构体,都会被放在同一个协程中统一处理,这样看起来使用Tick,Sleep并没有什么区别。实际上是有区别的,Sleep是使用睡眠完成定时任务,需要被调度唤醒。Tick函数是使用channel阻塞当前协程,完成定时任务的执行。当前并不清楚golang 阻塞和睡眠对资源的消耗会有什么区别,这方面不能给出建议。但是使用channel阻塞协程完成定时任务比较灵活,可以结合select设置超时时间以及默认执行方法,而且可以设置timer的主动关闭,以及不需要每次都生成一个timer(这方面节省系统内存,垃圾收回也需要时间)。所以,建议使用time.Tick完成定时任务。

time.after要比time.tick节省内存

相关文章

网友评论

      本文标题:Go定时任务

      本文链接:https://www.haomeiwen.com/subject/snebtktx.html