代碼: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 關注
- 120 瀏覽
添加回答
舉報
0/150
提交
取消