深入分析Sleep(0)與Sleep(1)的區別

目的:

有時候我們想讓線程不被調度一定的時間,也就是說讓線程睡眠一段時間。

API 接口:

在 Win32中可以調用 Sleep,SleepEx 和 SwitchToThread 三個API。

VOID WINAPI Sleep(DWORD dwMilliseconds);

DWORD WINAPI SleepEx(DWORD dwMilliseconds, BOOl bAlertable);

BOOl WINAPI SwitchToThread();

在託管代碼中,我們可以調用靜態方法 Thread.Sleep。

分析:

Sleep 接口均帶有表示睡眠時間長度的參數 timeout。調用以上提到的 Sleep 接口,會有條件地將調用線程從當前處理器上移除,並且有可能將它從線程調度器的可運行隊列中移除。這個條件取決於調用 Sleep 時timeout 參數。

當 timeout = 0, 即 Sleep(0),如果線程調度器的可運行隊列中有大於或等於當前線程優先級的就緒線程存在,操作系統會將當前線程從處理器上移除,調度其他優先級高的就緒線程運行;如果可運行隊列中的沒有就緒線程或所有就緒線程的優先級均低於當前線程優先級,那麼當前線程會繼續執行,就像沒有調用 Sleep(0)一樣。

當 timeout > 0 時,如:Sleep(1),會引發線程上下文切換:調用線程會從線程調度器的可運行隊列中被移除一段時間,這個時間段約等於 timeout 所指定的時間長度。爲什麼說約等於呢?是因爲睡眠時間單位爲毫秒,這與系統的時間精度有關。通常情況下,系統的時間精度爲 10 ms,那麼指定任意少於 10 ms但大於 0 ms 的睡眠時間,均會向上求值爲 10 ms。

而調用 SwitchToThread() 方法,如果當前有其他就緒線程在線程調度器的可運行隊列中,始終會讓出一個時間切片給這些就緒線程,而不管就緒線程的優先級的高低與否。

結論:

由上面的分析可以看出,如果我們想讓當前線程真正睡眠一下子,最好是調用 Sleep(1) 或 SwitchToThread()


發佈了4 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章