英文:
Ticker's behavior with time.sleep()
问题
代码部分已翻译如下:
func main() {
fmt.Println(time.Now())
ticker := time.NewTicker(100 * time.Millisecond)
done := make(chan bool)
go func() {
time.Sleep(900 * time.Millisecond)
for {
select {
case <-done:
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}()
time.Sleep(1600 * time.Millisecond)
ticker.Stop()
done <- true
fmt.Println("Ticker stopped")
}
输出部分已翻译如下:
2021-12-15 17:00:44.2506052 +0800 +08 m=+0.002777301
Tick at 2021-12-15 17:00:44.3916764 +0800 +08 m=+0.143848501
Tick at 2021-12-15 17:00:45.2913066 +0800 +08 m=+1.043478701
Tick at 2021-12-15 17:00:45.4007827 +0800 +08 m=+1.152954801
Tick at 2021-12-15 17:00:45.4930864 +0800 +08 m=+1.245258501
Tick at 2021-12-15 17:00:45.6021253 +0800 +08 m=+1.354297401
Tick at 2021-12-15 17:00:45.6980372 +0800 +08 m=+1.450209301
Tick at 2021-12-15 17:00:45.7929148 +0800 +08 m=+1.545086901
Tick at 2021-12-15 17:00:45.901921 +0800 +08 m=+1.654093101
Ticker stopped
问题部分已翻译如下:
- 为什么在 goroutine 中的 sleep 会暂停 ticker,而在主程序中的 sleep 不会?
- ticker.C 是非缓冲的,所以为什么不会有 16 个 tick?
- 为什么第一个 tick 的 m=+0.143848501?
请注意,我将不会回答关于翻译的问题。
英文:
Code:
func main() {
fmt.Println(time.Now())
ticker := time.NewTicker(100 * time.Millisecond)
done := make(chan bool)
go func() {
time.Sleep(900 * time.Millisecond)
for {
select {
case <-done:
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}()
time.Sleep(1600 * time.Millisecond)
ticker.Stop()
done <- true
fmt.Println("Ticker stopped")
}
Output:
2021-12-15 17:00:44.2506052 +0800 +08 m=+0.002777301
Tick at 2021-12-15 17:00:44.3916764 +0800 +08 m=+0.143848501
Tick at 2021-12-15 17:00:45.2913066 +0800 +08 m=+1.043478701
Tick at 2021-12-15 17:00:45.4007827 +0800 +08 m=+1.152954801
Tick at 2021-12-15 17:00:45.4930864 +0800 +08 m=+1.245258501
Tick at 2021-12-15 17:00:45.6021253 +0800 +08 m=+1.354297401
Tick at 2021-12-15 17:00:45.6980372 +0800 +08 m=+1.450209301
Tick at 2021-12-15 17:00:45.7929148 +0800 +08 m=+1.545086901
Tick at 2021-12-15 17:00:45.901921 +0800 +08 m=+1.654093101
Ticker stopped
Questions:
How do I interpret the result? More specifically:
- Why the sleep in the goroutine will pause the ticker while the sleep in the main routine will not?
- Is ticker.C non buffering so there aren't 16 ticks?
- Why the first tick has m=+0.143848501?
答案1
得分: 1
- 在断头台中的睡眠不会暂停计时器,它只会延迟第一次打印值的时刻。
- ticker.C 有一个大小为1的缓冲区。根据代码中的注释:
// 给通道一个1个元素的时间缓冲区。
// 如果客户端在读取时落后,我们会丢弃一些 tick,
// 直到客户端赶上为止。
因此,那里只有一个缓冲值。
- 第一个 tick 大约在计时器持续时间首次过去的时刻(约100毫秒左右)被写入通道。其他的 tick 然后被跳过,因为 ticker.C 中的缓冲区已满,并且在 time.Sleep 过后通道解除阻塞之前被丢弃,所以我们有了大约 900 毫秒的跳跃。
英文:
- The sleep in the goruotine doesn't pause the ticker, it delays the moment when the value is printed for the first time.
- ticker.C has a buffer of 1. According to comments in code:
// 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.
So there is only one buffered value there.
- The first tick is written into the channel roughly around the moment when the ticker duration passes for the first time ~100ms. Other ticks are then skipped because buffer in ticker.C is full and are dropped until the channel is unblocked after time.Sleep passes so we have a jump of ~900 ms.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论