一、線程的優先級
線程的優先級範圍從0(最低)到31(最高)。當你產生線程時,並不是直接以數值制定某優先級,而是採用兩個步驟。
第一個步驟是指定“優先級等級(Priority Class)”給進程,第二步驟是指定“相對優先級”給該進行的所有線程。其中的代碼在CreateProcess的dwCreationFlags參數中指定。如果你不指定,系統默認給的是NORMAL_PRIORITY_CLASS,除非父進程是IDLE_PRIORITY_CLASS(那麼子進程也會是IDLE_PRIORITY_CLASS)。
要改變線程的優先級,用如下函數:
BOOL SetThreadPriority(HANDLE hThread,int nPriority)
二、線程的優先級值
SetThreadPriority的參數:
THREAD_PRIORITY_IDLE 空閒
THREAD_PRIORITY_LOWEST 最低
THREAD_PRIORITY_BELOW_NORMAL 低於正常
THREAD_PRIORITY_NORMAL 正常
THREAD_PRIORITY_ABOVE_NORMAL 高於正常
THREAD_PRIORITY_HIGHEST 最高
THREAD_PRIORITY_TIME_CRITICAL 實時
三、運行實例
#include <iostream>
#include <Windows.h>
using namespace std;
DWORD WINAPI ThreadIdle(LPVOID lpParam)
{
int i = 0;
while (i++ < 10)
{
printf("Idle線程正在運行\n");
}
return 0;
}
DWORD WINAPI ThreadNormal(LPVOID lpParam)
{
int i = 0;
while (i++ < 10)
{
printf("Normal線程正在運行\n");
}
return 0;
}
int main()
{
DWORD ThreadId[2];
HANDLE h[2];
// 創建線程1,置其狀態爲掛起狀態
h[0] = ::CreateThread(NULL, 0, ThreadIdle, NULL,
CREATE_SUSPENDED, &ThreadId[0]);
// 設置優先級與IDLE
::SetThreadPriority(h[0], THREAD_PRIORITY_IDLE);
// 喚醒線程
::ResumeThread(h[0]);
// 創建線程2
h[1] = ::CreateThread(NULL, 0, ThreadNormal, NULL,
0, &ThreadId[1]);
::WaitForMultipleObjects(
2, // 表示我們要等待的線程的內核對象的數量
h,
TRUE,// 只有都完成了才能結束
INFINITE
);
system("pause");
return 0;
}
四、運行結果
爲甚兩次執行的結果並不一樣,低優先級的線程爲什麼會比高優先級的線程先執行??
五、爲什麼低優先級的線程會比高優先級的線程先執行
在我們的操作系統當中,我們操作系統內核調用了若干個線程指定序列,然後指令序列開始推進,指令序列的優先級叫做相對優先級概念。
什麼叫做相對優先級?在我們實際的開發過程當中,我們可能聽說過操作系統中一個非常重要的知識,那就是儘可能多的使用CPU,CPU使用的越多,那麼就代表着CPU的計算任務越重,資源就可以得到充分的利用。
短作業優先,耗時短的任務越先讓CPU執行,那麼所有的作業,在任務完畢的時候,使得所有作業的平均等待時間最短。
看上去這是一個非常優化的算法,但是這樣存在一個非常大的弊端,比如,作業來的很早,作業運行耗時很長,那麼在它還沒有運行之前來了一個比它運行時間段的任務進入CPU的就緒隊列,那麼CPU就會先推進那個耗時短的作業,這樣就會造成公平性的喪失。
在Windows系統中,其實也考慮過這個問題,我們的優先級並不是絕對優先級,在絕大多數情況下用戶態的優先級都是相對的,那麼操作系統就會調度,這樣就會造成Normal優先級與Idle優先並不是嚴格的按照高優先級先運行,低優先後運行。操作系統也考慮到了公平性與效率性的問題。
Idle線程優先於Normal線程調用,在我們的調度過程當中,我麼現在的系統已經是多核的,不在像以前一樣,只有一個單核,那麼在多核的情況下,A核與B核這個假定,主線程可能是和某一個線程在A核當中,另一個線程分發到另一個空閒的核當中,那麼這就會造成低優先級的線程先於高優先的線程調用。
優先級只是一個相對的概念,不要想當然的認爲高優先級的線程一定會先於低優先級的線程調用。