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