美文网首页
go定时器NewTicker&NewTimer

go定时器NewTicker&NewTimer

作者: 我帅的不忍直视 | 来源:发表于2020-02-16 15:38 被阅读0次

    1.NewTimer:

    func NewTimer(d Duration) *Timer {}

    d时间段后触发

    for {

    select {

    case <-t.C:

    fmt.Println("timer触发")

    if 循环 {

    t.Reset(delat)

    }

    case <done:

    return

    }

    }

    NewTimer是延迟d时间后触发,如果需要循环则需要Reset。NewTimer的延迟时间并不是精确、稳定的,比如设置30ms,有可能会35、40ms后才触发,即使在系统资源充足的情况下,所以一个循环的timer在60ms内并不能保证会触发2两次,而ticker会。

    2.NewTicker:

    func NewTicker(d Duration) *Ticker {}

    每隔时间段 d 就向该通道发送当时的时间;

    go func(timer *Timer) {

    defer timer.t.Stop()

    for {

    select {

    case <-timer.t.C:

    fmt.Println("ticker 触发")

    case <-timer.done:

    fmt.Println("ticker 关闭")

    return

    }

    }

    }(t)

    它会调整时间间隔或者丢弃 tick 信息以适应反应慢的接者,所以回调触发不是稳定的,有可能在小于d的时间段触发,也有可能大于d的时间段触发,即使应用什么都不做。但在一段时间内,触发次数是保证的,比如在系统资源充足的情况下,设定触发间隔30ms,上一ticket触发间隔是44ms,下一触发间隔可能就是16ms,所以60ms内还是会触发两个ticket。

    相似处:都可以实现一个定时器,timer需要每次reset时间。

    区别:ticker的稳定性不如timer,一个空转的go程序,tickter也是不稳定的,触发间隔并不会稳定在d时间段,在ms级别上;而timer相对稳定,但也不是绝对的,timer也会在大于d的时间后触发。

    综上所述,在ms级别定期刷新的定时器,ticket不够稳定但触发次数在一段时间内是固定的(也不是肯定固定,任务处理耗时非常大),timer相对稳定,但总有几个帧会在大于d的时间后触发,导致时间间隔累计值与实际时间戳差值误差越来越大。

    所以如果想使用正确的刷新时间,建议使用NewTimer结合时间戳差值来保证程序刷新的正确性,不要利用d的累加或类减作为时间计算因子。

    相关文章

      网友评论

          本文标题:go定时器NewTicker&NewTimer

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