簡體   English   中英

對於`std :: this_thread :: sleep_for()`有任何特定於平台的限制嗎?

[英]Are there any platform-specific limitations to `std::this_thread::sleep_for()`?

在使用std::this_thread::sleep_for()毫秒和向上時,是否有任何已知的可移植性問題需要考慮?

在我正在開發的一個項目中,我希望能夠替換一系列特定於平台的實現,這些實現都是為了產生指定的毫秒數而提供或者使用,使用從Microsoft的Sleep()naonsleep()usleep任何東西,具體取決於在特定平台上可用的內容。 其中一些具有明顯的局限性,例如在某些平台上不支持1000毫秒或更長的延遲。

std::this_thread::sleep_for()遭受這樣的怪癖嗎?

最大睡眠持續時間: std::this_thread::sleep_for()在這里沒有任何問題。 只要你願意,你就可以睡覺。

精度: std::this_thread::sleep_for()有同樣的問題,你提到的所有其他睡眠功能也有: 可能不是! 見下面的更新!

當您的任務實際恢復時,任何睡眠功能都會受到這樣的quirk ,即它完全取決於操作系統中的調度程序。 您的睡眠時間通常會在搶占式多任務調度程序的最小時間片周圍有所不同。

更糟糕的是,這個時間片在所有操作系統上並不總是不變的。

在Linux上,您通常有10毫秒的時間片,睡眠時間小於10毫秒可能導致睡眠時間為0毫秒。 睡眠10毫秒可能導致睡眠 10毫秒或更長時間,可能但不一定與時間片大小對齊。

簡而言之:您根本無法依賴任何睡眠函數,包括std::this_thread::sleep_for()

還有另一類睡眠功能,可以忙着等待。 這通常在等待明顯短於調度時間片(例如2 us)的時間時使用。 但是,當然即使這可能是非常不准確的,因為即使在幾乎空閑的系統上你的任務也可能被搶占,然后你可以為你的2 us睡眠時間增加10 ms。

在多任務操作系統上,您沒有機會:您無法准確入睡。 睡眠功能有錯誤,甚至有系統錯誤,因此睡眠100次10毫秒可能會在0到2秒之間睡眠。

如果您有長期時間要求,您唯一的機會就是不斷查詢掛鍾時間。

更新:Linux和macOS的基准測試:

至少在Linux和macOS上, std::this_thread::sleep_for()對於毫秒分辨率非常精確,因此不會受到我上面描述的所有工件的影響:

Linux基准測試:每次睡眠被重復調用,持續時間為一秒,並給出實際平均睡眠時間(例如,平均超過200次睡眠呼叫(5毫秒)):

std::this_thread::sleep( 1 ms) slept really 1.13915 ms
std::this_thread::sleep( 2 ms) slept really 2.15215 ms
std::this_thread::sleep( 3 ms) slept really 3.14976 ms
std::this_thread::sleep( 4 ms) slept really 4.15059 ms
std::this_thread::sleep( 5 ms) slept really 5.15062 ms
std::this_thread::sleep( 6 ms) slept really 6.15008 ms
std::this_thread::sleep( 7 ms) slept really 7.14988 ms
std::this_thread::sleep( 8 ms) slept really 8.14979 ms
std::this_thread::sleep( 9 ms) slept really 9.15044 ms
std::this_thread::sleep(10 ms) slept really 10.1504 ms
std::this_thread::sleep(11 ms) slept really 11.1511 ms
std::this_thread::sleep(12 ms) slept really 12.1505 ms
std::this_thread::sleep(13 ms) slept really 13.1504 ms
std::this_thread::sleep(14 ms) slept really 14.1501 ms
std::this_thread::sleep(15 ms) slept really 15.1503 ms
std::this_thread::sleep(16 ms) slept really 16.1499 ms
std::this_thread::sleep(17 ms) slept really 17.1505 ms
std::this_thread::sleep(18 ms) slept really 18.1505 ms
std::this_thread::sleep(19 ms) slept really 19.1504 ms
std::this_thread::sleep(20 ms) slept really 20.1505 ms

對於macOS也是如此:

std::this_thread::sleep( 1 ms) slept really 1.27451 ms
std::this_thread::sleep( 2 ms) slept really 2.45646 ms
std::this_thread::sleep( 3 ms) slept really 3.61991 ms
std::this_thread::sleep( 4 ms) slept really 4.77443 ms
std::this_thread::sleep( 5 ms) slept really 5.7994 ms
std::this_thread::sleep( 6 ms) slept really 7.03769 ms
std::this_thread::sleep( 7 ms) slept really 8.13089 ms
std::this_thread::sleep( 8 ms) slept really 9.13276 ms
std::this_thread::sleep( 9 ms) slept really 10.441 ms
std::this_thread::sleep(10 ms) slept really 11.5895 ms
std::this_thread::sleep(11 ms) slept really 12.77 ms
std::this_thread::sleep(12 ms) slept really 13.8207 ms
std::this_thread::sleep(13 ms) slept really 14.9366 ms
std::this_thread::sleep(14 ms) slept really 16.4569 ms
std::this_thread::sleep(15 ms) slept really 17.27 ms
std::this_thread::sleep(16 ms) slept really 18.2013 ms
std::this_thread::sleep(17 ms) slept really 19.6347 ms
std::this_thread::sleep(18 ms) slept really 20.7785 ms
std::this_thread::sleep(19 ms) slept really 22.9571 ms
std::this_thread::sleep(20 ms) slept really 23.2532 ms

兩次運行都在空閑系統上。 有趣的是:在Linux上,數字在加載的系統上變得更加精確(在屏幕會話中是的)。 調度器工件! 但小的! :-)

這適用於Linux上的usleep() :也非常精確。 我不再相信我上面寫的內容:

usleep( 1 ms) slept really  1.148 ms
usleep( 2 ms) slept really  2.152 ms
usleep( 3 ms) slept really  3.151 ms
usleep( 4 ms) slept really  4.151 ms
usleep( 5 ms) slept really  5.149 ms
usleep( 6 ms) slept really  6.149 ms
usleep( 7 ms) slept really  7.149 ms
usleep( 8 ms) slept really  8.150 ms
usleep( 9 ms) slept really  9.150 ms
usleep(10 ms) slept really 10.150 ms
usleep(11 ms) slept really 11.149 ms
usleep(12 ms) slept really 12.149 ms
usleep(13 ms) slept really 13.150 ms
usleep(14 ms) slept really 14.150 ms
usleep(15 ms) slept really 15.149 ms
usleep(16 ms) slept really 16.149 ms
usleep(17 ms) slept really 17.150 ms
usleep(18 ms) slept really 18.150 ms
usleep(19 ms) slept really 19.149 ms
usleep(20 ms) slept really 20.149 ms

sleep_for支持更長的延遲,因為它接受任何有效的持續時間值。 但是,它確實有局限性:

sleep_for通常使用std::chrono::steady_clock ,因此受到該時鍾的限制。 該標准要求時鍾單調前進。 但決議可能因實施而異。

也,

由於調度或資源爭用延遲,此功能可能會阻塞比sleep_duration更長的時間。 sleep_for(cpp參考)

所以sleep_for可能會睡眠時間超過指定時間。

暫無
暫無

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

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