C++系列 --- 低優先級的線程爲什麼會被先執行

一、線程的優先級

線程的優先級範圍從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;
}

四、運行結果

執行結果1
執行結果1
執行結果1

爲甚兩次執行的結果並不一樣,低優先級的線程爲什麼會比高優先級的線程先執行?? 

五、爲什麼低優先級的線程會比高優先級的線程先執行

 在我們的操作系統當中,我們操作系統內核調用了若干個線程指定序列,然後指令序列開始推進,指令序列的優先級叫做相對優先級概念。

什麼叫做相對優先級?在我們實際的開發過程當中,我們可能聽說過操作系統中一個非常重要的知識,那就是儘可能多的使用CPU,CPU使用的越多,那麼就代表着CPU的計算任務越重,資源就可以得到充分的利用。

短作業優先,耗時短的任務越先讓CPU執行,那麼所有的作業,在任務完畢的時候,使得所有作業的平均等待時間最短。

看上去這是一個非常優化的算法,但是這樣存在一個非常大的弊端,比如,作業來的很早,作業運行耗時很長,那麼在它還沒有運行之前來了一個比它運行時間段的任務進入CPU的就緒隊列,那麼CPU就會先推進那個耗時短的作業,這樣就會造成公平性的喪失。

在Windows系統中,其實也考慮過這個問題,我們的優先級並不是絕對優先級,在絕大多數情況下用戶態的優先級都是相對的,那麼操作系統就會調度,這樣就會造成Normal優先級與Idle優先並不是嚴格的按照高優先級先運行,低優先後運行。操作系統也考慮到了公平性與效率性的問題。

Idle線程優先於Normal線程調用,在我們的調度過程當中,我麼現在的系統已經是多核的,不在像以前一樣,只有一個單核,那麼在多核的情況下,A核與B核這個假定,主線程可能是和某一個線程在A核當中,另一個線程分發到另一個空閒的核當中,那麼這就會造成低優先級的線程先於高優先的線程調用。

優先級只是一個相對的概念,不要想當然的認爲高優先級的線程一定會先於低優先級的線程調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章