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"))
}
}
上面代码段的输出是:
开始时间 2016-06-22 16:22:20
滴答时间 2016-06-22 16:22:23
滴答时间 2016-06-22 16:22:35
滴答时间 2016-06-22 16:22:38
滴答时间 2016-06-22 16:22:41
滴答时间 2016-06-22 16:22:44
为什么当我延迟代码时没有时间戳 16:22:26、16:22:29 会发生这种情况?
最佳答案
这是 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.
发生了什么:
- 您创建计时器
- 计时器产生它的第一个滴答声并缓冲它。
- 现在它会等待、唤醒并阻塞,等待您消费以便它可以产生第 2 次滴答。
- 最终,您的 goroutine 醒来并立即消耗它产生的前两个滴答声,然后它再次开始产生滴答声。
编辑:此外,NewTicker
的文档(Tick
是一个方便的函数)说:
NewTicker returns a new Ticker containing a channel that will send the time with a period specified by the duration argument. It adjusts the intervals or drops ticks to make up for slow receivers. The duration d must be greater than zero; if not, NewTicker will panic. Stop the ticker to release associated resources.
虽然它没有明确提到它是一个缓冲区为 1 的 channel 。
关于go - golang 自动收报机是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37962666/