代码: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.002777301Tick at 2021-12-15 17:00:44.3916764 +0800 +08 m=+0.143848501Tick at 2021-12-15 17:00:45.2913066 +0800 +08 m=+1.043478701Tick at 2021-12-15 17:00:45.4007827 +0800 +08 m=+1.152954801Tick at 2021-12-15 17:00:45.4930864 +0800 +08 m=+1.245258501Tick at 2021-12-15 17:00:45.6021253 +0800 +08 m=+1.354297401Tick at 2021-12-15 17:00:45.6980372 +0800 +08 m=+1.450209301Tick at 2021-12-15 17:00:45.7929148 +0800 +08 m=+1.545086901Tick at 2021-12-15 17:00:45.901921 +0800 +08 m=+1.654093101Ticker stopped问题:我如何解释结果?进一步来说:为什么 goroutine 中的 sleep 会暂停 ticker 而 main 例程中的 sleep 不会?是ticker.C 非缓冲所以没有16 个滴答声?为什么第一个刻度有 m=+0.143848501?
1 回答

守着星空守着你
TA贡献1799条经验 获得超8个赞
goruotine 中的睡眠不会暂停代码,它会延迟第一次打印值的时刻。
ticker.C 的缓冲区为 1。根据代码中的注释:
// 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.
所以那里只有一个缓冲值。
第一个刻度大约在刻度持续时间第一次经过约 100 毫秒的那一刻被写入通道。然后跳过其他滴答声,因为ticker.C 中的缓冲区已满并被丢弃,直到通道在 time.Sleep 之后被解除阻塞,所以我们有大约 900 毫秒的跳跃。
- 1 回答
- 0 关注
- 121 浏览
添加回答
举报
0/150
提交
取消