簡體   English   中英

Go:時間的意外結果。睡眠

[英]Go: Unexpected Results from time.Sleep

運行此代碼(作為構建的可執行文件,而不是使用調試器):

package main

import (
    "fmt"
    "time"
)

func main() {
    startTime := time.Now()
    for i := 0; i < 1000; i++ {
        time.Sleep(1 * time.Millisecond)
    }
    fmt.Printf("%d\n", time.Since(startTime).Milliseconds())
}

我得到 output:

15467

這似乎是調用time.Sleep() function; 的主要開銷。 它實際上每次循環迭代需要 15 毫秒,即使它在每個循環中只休眠 1 毫秒。 這表明運行循環迭代和啟動睡眠有 14 毫秒的開銷。

如果我們調整睡眠時長:

package main

import (
    "fmt"
    "time"
)

func main() {
    startTime := time.Now()
    for i := 0; i < 1000; i++ {
        time.Sleep(10 * time.Millisecond)
    }
    fmt.Printf("%d\n", time.Since(startTime).Milliseconds())
}

我得到 output:

15611

這基本上是相同的持續時間,即使它應該休眠 10 倍的時間。 這消除了循環迭代和啟動睡眠有 14 毫秒開銷的想法,因為如果是這種情況,那么總共將是 (14+10)*1000 = 24000 毫秒,但事實並非如此。

我錯過了什么? 為什么這段代碼的執行時間相同,不管睡眠時間是 1 毫秒還是 10 毫秒?

請注意,我已經嘗試在 Go 操場上運行它,但得到不同的結果; 我認為它處理睡眠的方式不同。 這些結果在我運行 i7-10510 的筆記本電腦上是一致的。

這可能與系統定時器的頻率有關。 例如,在 Windows 上,時鍾每 15 毫秒滴答一次( 來源):

例如,對於在 x86 處理器上運行的 Windows,系統時鍾節拍之間的默認間隔通常約為 15 毫秒,系統時鍾節拍之間的最小間隔約為 1 毫秒。 因此,默認分辨率計時器(如果未設置 EX_TIMER_HIGH_RESOLUTION 標志,則由 ExAllocateTimer 創建)的到期時間只能控制在大約 15 毫秒內,但高分辨率計時器的到期時間可以控制在毫秒內.

如果您需要更高精度的計時器,您可能需要找到一種使用高分辨率計時器的方法。

更多信息可以在下面的線程中找到:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM