1 回答
TA貢獻1818條經驗 獲得超8個贊
該軟件包benbjohnson/clock提供模擬時間設施。他們的文檔特別指出:
計時器和 Tickers 也由同一個模擬時鐘控制。它們只會在時鐘向前移動時執行
所以當你調用時mockClock.Add,它會依次執行定時器/代碼。該庫還添加了連續的 1 毫秒睡眠,以人為地屈服于其他 goroutines。
當計時器/自動收報機在 goroutine 外部聲明時,即在調用之前mockClock.Add,到mockClock.Add被調用時,模擬時間確實有一些東西要執行。庫的內部睡眠足以讓子 goroutine 在程序退出之前在自動收報機上接收并打印“完成”。
當 ticker 在 goroutine 中聲明時,到 timemockClock.Add被調用時,模擬時間沒有要執行的 ticker,Add基本上什么都不做。內部睡眠確實給了子 goroutine 運行的機會,但是接收到 ticker 現在只會阻塞;main 然后恢復并退出。
您還可以查看存儲庫自述文件中的代碼示例:
mock := clock.NewMock()
count := 0
// Kick off a timer to increment every 1 mock second.
go func() {
ticker := mock.Ticker(1 * time.Second)
for {
<-ticker.C
count++
}
}()
runtime.Gosched()
// Move the clock forward 10 seconds.
mock.Add(10 * time.Second)
// This prints 10.
fmt.Println(count)
這用于在調用之前runtime.Gosched()屈服于子 goroutine 。這個程序的順序基本上是:mock.Add
clock.NewMock()count := 0生成子 goroutine
runtime.Gosched(), 讓步給子 goroutineticker := mock.Ticker(1 * time.Second)阻塞
<-ticker.C(模擬時鐘還沒有向前移動)恢復主要
mock.Add, 它將時鐘向前移動并再次讓步給子 goroutinefor循環<-ticker.C打印 10
出口
按照相同的邏輯,如果您將 a 添加runtime.Gosched()到第二個代碼段,它將按預期工作,就像存儲庫的示例一樣。游樂場:https ://go.dev/play/p/ZitEdtx9GdL
但是,不要依賴runtime.Gosched()生產代碼,甚至可能不要依賴測試代碼,除非您非常確定自己在做什么。
最后,請記住time.Sleep(1)休眠一納秒。
- 1 回答
- 0 關注
- 158 瀏覽
添加回答
舉報
