【问题标题】:How does golang ticker work?golang 代码是如何工作的?
【发布时间】:2016-06-22 08:34:36
【问题描述】:
func Tick() {                                                                                                                                         
    fmt.Println("startTime", time.Now().Format("2006-01-02 15:04:05"))                                                                                
    t := time.NewTicker(time.Second * 3)                                                                                                              
    time.Sleep(time.Second * 12)                                                                                                                      
    for {                                                                                                                                             
        stamp := <-t.C                                                                                                                                
        fmt.Println("tickTime", stamp.Format("2006-01-02 15:04:05"))                                                                                  
    }                                                                                                                                                 
}          

sn-p 上面的输出是:

开始时间 2016-06-22 16:22:20

tickTime 2016-06-22 16:22:23

tickTime 2016-06-22 16:22:35

tickTime 2016-06-22 16:22:38

tickTime 2016-06-22 16:22:41

tickTime 2016-06-22 16:22:44


当我延迟代码时,为什么会在没有时间戳 16:22:26、16:22:29 的情况下发生这种情况?

【问题讨论】:

  • 你在哪里运行这个?这对我来说似乎很好用:play.golang.org/p/3uVTJq9AfN
  • @DuruCanCelasun 您只等待 1 秒,这比代码持续时间短。等待 > 滴答持续时间是这里的问题。

标签: go ticker


【解决方案1】:

这是 Ticker 源代码(请原谅行号,我从文档源页面复制了这个):

    func NewTicker(d Duration) *Ticker {
            if d <= 0 {
                panic(errors.New("non-positive interval for NewTicker"))
            }
            // Give the channel a 1-element time buffer.
            // If the client falls behind while reading, we drop ticks
            // on the floor until the client catches up.
            c := make(chan Time, 1)
            t := &Ticker{
                C: c,
                r: runtimeTimer{
                    when:   when(d),
                    period: int64(d),
                    f:      sendTime,
                    arg:    c,
                },
            }
            startTimer(&t.r)
            return t
        }

注意评论

// Give the channel a 1-element time buffer.
// If the client falls behind while reading, we drop ticks
// on the floor until the client catches up.

发生了什么:

  1. 您创建计时器
  2. 计时器产生其第一个滴答声并对其进行缓冲。
  3. 现在它会等待、唤醒和阻塞,等待您消费,以便它可以产生第 2 次滴答。
  4. 最终,您的 goroutine 唤醒并立即消耗它产生的前两个滴答声,然后再次开始产生滴答声。

编辑:此外,NewTickerTick 是一个便利功能)的文档说:

NewTicker 返回一个新的 Ticker,其中包含一个将发送 具有由持续时间参数指定的时间段的时间。它调整 间隔或滴答滴答以弥补慢速接收器。持续时间 d 必须大于零;如果没有,NewTicker 会恐慌。停止 用于释放相关资源的代码。

虽然它没有明确提到它是一个缓冲区为 1 的通道。

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 2014-08-11
    • 2011-05-16
    • 2014-05-10
    • 2017-08-08
    • 1970-01-01
    • 2016-12-31
    相关资源
    最近更新 更多