有時候我們想讓線程不被調(diào)度一定的時間,也就是說讓線程睡眠一段時間。
API 接口:
在 Win32中可以調(diào)用 Sleep,SleepEx 和 SwitchToThread 三個API。
VOID WINAPI Sleep(DWORD dwMilliseconds);
DWORD WINAPI SleepEx(DWORD dwMilliseconds, BOOl bAlertable);
BOOl WINAPI SwitchToThread();
在托管代碼中,我們可以調(diào)用靜態(tài)方法 Thread.Sleep。
分析:
Sleep 接口均帶有表示睡眠時間長度的參數(shù) timeout。調(diào)用以上提到的 Sleep 接口,會有條件地將調(diào)用線程從當前處理器上移除,并且有可能將它從線程調(diào)度器的可運行隊列中移除。這個條件取決于調(diào)用 Sleep 時timeout 參數(shù)。
當 timeout = 0, 即 Sleep(0),如果線程調(diào)度器的可運行隊列中有大于或等于當前線程優(yōu)先級的就緒線程存在,操作系統(tǒng)會將當前線程從處理器上移除,調(diào)度其他優(yōu)先級高的就緒線程運行;如果可運行隊列中的沒有就緒線程或所有就緒線程的優(yōu)先級均低于當前線程優(yōu)先級,那么當前線程會繼續(xù)執(zhí)行,就像沒有調(diào)用 Sleep(0)一樣。
當 timeout > 0 時,如:Sleep(1),會引發(fā)線程上下文切換:調(diào)用線程會從線程調(diào)度器的可運行隊列中被移除一段時間,這個時間段約等于 timeout 所指定的時間長度。為什么說約等于呢?是因為睡眠時間單位為毫秒,這與系統(tǒng)的時間精度有關(guān)。通常情況下,系統(tǒng)的時間精度為 10 ms,那么指定任意少于 10 ms但大于 0 ms 的睡眠時間,均會向上求值為 10 ms。
而調(diào)用 SwitchToThread() 方法,如果當前有其他就緒線程在線程調(diào)度器的可運行隊列中,始終會讓出一個時間切片給這些就緒線程,而不管就緒線程的優(yōu)先級的高低與否。
結(jié)論:
由上面的分析可以看出,如果我們想讓當前線程真正睡眠一下子,最好是調(diào)用 Sleep(1) 或 SwitchToThread()。