2012-11-29 34 views
3

我不明白如何使用SetThreadPrioritySetPriorityClass來降低和提高線程的優先級。SetThreadPriority和SetPriorityClass

我的理解是,SetPriorityClass選擇一個進程可用的優先級範圍,而SetThreadPriority設置該類內的相對優先級。

例如,什麼是這樣做了線程的結果:

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN); 

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END); 

感謝您的幫助。

+0

如果您想試驗,請使用GetThreadPriority()。 –

+0

您可以閱讀本文以瞭解Android SDK如何在Runnable中使用setThreadPriority:http://developer.android.com/training/multiple-threads/define-runnable.html –

回答

2

進程優先級和線程優先級正在構建線程的base priority。請參見Scheduling Priorities以查找優先級如何組合。通過查看這個列表,你的理解變得很清楚了,在某個優先等級內,base priority可以具有各種值,由thread priority確定。

所有Windows版本都不支持SetPriorityClassTHREAD_MODE_BACKGROUND_END值的PROCESS_MODE_BACKGROUND_BEGIN值。

PROCESS_MODE_BACKGROUND_BEGIN: 該系統降低了工藝(及其線程)的資源調度優先級,以便它可以無需在前臺顯著影響活動進行後臺工作。

THREAD_MODE_BACKGROUND_END: 終止後臺處理模式。系統恢復線程的資源調度優先級,就像線程進入後臺處理模式之前一樣。

此處可能出現的情景的後果是可預測的:SetPriorityClass將會將其所有線程的進程設置爲background processing mode。以下SetThreadPriority將只從background processing mode發佈一個線程。但進程的所有其他可能線程將保持處於後臺處理模式。

注:只有process priority classthread priority組合確定base priority。因此,對GetThreadPriority的呼叫和對GetPriorityClass的呼叫都不會返回基本優先級。只有它們的組合才能釋放上面「計劃優先級」鏈接中描述的基本優先級。不幸的是,新的background processing mode值尚未包含在base priority列表中。但名稱base priority說明了這裏的重要內容:根據基本優先級(從進程優先級和線程優先級派生而來),調度程序可以動態調整調度優先級。後臺模式只是fine tune調度優先級的另一種方式。另一種方式是Priority Boosts。優先級提升功能存在一段時間。對SetThreadPrioritySetPriorityClassbackground processing mode值的新訪問直接打開了優先級提升功能。在Windows XP中,這必須通過致電SetProcessPriorityBoost來完成。

+0

嗨,我發現THREAD_MODE_BACKGROUND_END無法撤銷PROCESS_MODE_BACKGROUND_BEGIN的所有效果。看到我的答案。 –

+0

@RolandPihlakas:** THREAD_MODE_BACKGROUND_END:**取自[MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686277%28v=vs.85%29.aspx):你是否聲明'PROCESS_MODE_BACKGROUND_BEGIN'永久地將工作集大小限制在一個相當小的範圍內?你認爲它使用[EmptyWorkingSet](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682606%28v=vs.85%29.aspx)函數。您是否使用[GetProcessWorkingSetSizeEx](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683227%28v=vs.85%29.aspx)進行了雙重檢查?這將是非常有趣的! WinVersion? – Arno

+0

我使用'GetProcessWorkingSetSizeEx'進行了檢查:在進入後臺模式後,最大工作集將被限制爲32MB,並且'QUOTA_LIMITS_HARDWS_MAX_ENABLE'標誌也被設置。如果我沒有進入後臺模式,那麼最大工作集參數甚至是一個非常小的值:大約1.35MB,即使在我的巨大內存分配之後。但是由於設置了「QUOTA_LIMITS_HARDWS_MAX_DISABLE」標誌,所以最大工作集對實際工作集沒有這樣或那樣的影響。我不知道是否調用了'EmptyWorkingSet',但據我瞭解,它無論如何不會改變工作集參數? –

2

一件事PROCESS_MODE_BACKGROUND_BEGIN,我觀察到,但已顯然沒有被記錄在案,就是至少在Windows 7下它清空工作集的過程中永久,不管過程如何訪問內存 - 直到後臺模式結束。

例如,通常不PROCESS_MODE_BACKGROUND_BEGIN,當我的機器具有的可用內存千兆字節,並且該過程需要消耗不斷的存儲器過程千兆字節,所述過程工作集將大約等於分配大小。也就是說,該進程獲取它在其工作集中使用的所有內存。好。
現在,與PROCESS_MODE_BACKGROUND_BEGIN工作集將幾十兆!
不好的結果是,這導致不斷頁錯誤和計算運行速度慢得多!頁面錯誤很可能不是頁面文件,而是Windows緩存。但頁面錯誤仍然會顯着減慢計算速度,同時也會導致CPU消耗無意義的負載。

總之,PROCESS_MODE_BACKGROUND_BEGIN不適合低優先級的背景工作。這項工作將是非常耗時的能源效率低下
PROCESS_MODE_BACKGROUND_BEGIN只適用於過程真的不打算在後臺消耗任何東西

與此相反,THREAD_MODE_BACKGROUND_BEGIN沒有這種可怕的效果,即使線程是進程中唯一的線程。
另請注意,您需要關閉PROCESS_MODE_BACKGROUND_BEGIN,只使用PROCESS_MODE_BACKGROUND_END。在PROCESS_MODE_BACKGROUND_BEGIN之後撥打THREAD_MODE_BACKGROUND_END是不夠的。
因此,Arno並不完全正確,即使對於單個線程,THREAD_MODE_BACKGROUND_END也可以解除PROCESS_MODE_BACKGROUND_BEGIN的影響。

備註:SetProcessPriorityBoostbDisablePriorityBoost = TRUE對工作集沒有任何影響。