日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

线程的调度、优先级和亲缘性——Windows核心编程学习手札系列之七

發(fā)布時(shí)間:2025/4/16 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程的调度、优先级和亲缘性——Windows核心编程学习手札系列之七 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線(xiàn)程的調(diào)度、優(yōu)先級(jí)和親緣性

——Windows核心編程學(xué)習(xí)手札系列之七

每個(gè)線(xiàn)程都擁有一個(gè)上下文結(jié)構(gòu),在線(xiàn)程的內(nèi)核對(duì)象中,記錄線(xiàn)程上次運(yùn)行時(shí)該線(xiàn)程的CPU寄存器狀態(tài)。Windows會(huì)每隔20ms左右查看當(dāng)前存在的所有線(xiàn)程內(nèi)核對(duì)象,在這些對(duì)象中,選擇可調(diào)度的對(duì)象,將其上下文結(jié)構(gòu)(內(nèi)核對(duì)象中)加載到CPU的寄存器中,其值就是上次保存在線(xiàn)程環(huán)境中的值,此為上下文切換。Windows保存了一個(gè)記錄,說(shuō)明每個(gè)線(xiàn)程獲得調(diào)度的機(jī)會(huì),MicrosoftSpy++工具,可以查看這個(gè)。操作系統(tǒng)只調(diào)度可以調(diào)度的線(xiàn)程,實(shí)際中,大多數(shù)線(xiàn)程是不可調(diào)度的,如暫停的線(xiàn)程(CREATE_SUSPENDED標(biāo)志)以及等待事件觸發(fā)的線(xiàn)程等。

線(xiàn)程內(nèi)核對(duì)象的內(nèi)部有線(xiàn)程的暫停計(jì)數(shù)值,當(dāng)調(diào)用CreateProcessCreateThread函數(shù)時(shí),就創(chuàng)建了線(xiàn)程的內(nèi)核對(duì)象,且它的暫停計(jì)數(shù)被初始化為1,防止線(xiàn)程被調(diào)度到CPU中,因?yàn)榫€(xiàn)程初始化需要時(shí)間,需要在準(zhǔn)備好開(kāi)始執(zhí)行線(xiàn)程。當(dāng)線(xiàn)程完全初始化后,CreateProcessCreateThread要查看是否傳遞了CREATE_SUSPENDED標(biāo)志,如果傳遞了給標(biāo)志,那函數(shù)返回,新線(xiàn)程處于暫停狀態(tài);如未傳遞該標(biāo)志,那函數(shù)將線(xiàn)程的暫停計(jì)數(shù)遞減為0,此時(shí)如果線(xiàn)程沒(méi)有等待事件,那么該線(xiàn)程處在可調(diào)度的狀態(tài)。在暫停狀態(tài)中創(chuàng)建一個(gè)線(xiàn)程,就可以在線(xiàn)程有機(jī)會(huì)執(zhí)行前改變線(xiàn)程的運(yùn)行環(huán)境(如優(yōu)先級(jí))。要恢復(fù)線(xiàn)程的可調(diào)度性,可調(diào)用函數(shù)ResumeThread,將調(diào)用CreateThread函數(shù)時(shí)返回的線(xiàn)程句柄傳遞給它。DWORD ResumeThread(HANDLE hThread)運(yùn)行成功將返回線(xiàn)程的前一個(gè)暫停計(jì)數(shù),否則返回0xFFFFFFFF值,單個(gè)線(xiàn)程可以暫停若干次,如一個(gè)線(xiàn)程序暫停了3次需要恢復(fù)3次才可以被分配給一個(gè)CPU。創(chuàng)建線(xiàn)程,除傳遞CREATE_SUSPENDED標(biāo)志外,還可以調(diào)用DWORD SuspendThread(HANDLE hThread)函數(shù)來(lái)暫停線(xiàn)程的運(yùn)行。任何線(xiàn)程都可以調(diào)用該函數(shù)來(lái)暫停另一個(gè)線(xiàn)程的運(yùn)行(只要有線(xiàn)程的句柄),線(xiàn)程可以自行暫停運(yùn)行,但不能自行恢復(fù)運(yùn)行。與ResumeThread一樣,SuspendThread返回的是線(xiàn)程的一個(gè)暫停計(jì)數(shù),暫停計(jì)數(shù)最多是MAXIMUM_SUSPEND_COUNT次(在WinNT.h中定義為127),SuspendThread與內(nèi)核方式是異步運(yùn)行的,但在線(xiàn)程恢復(fù)運(yùn)行之前,不會(huì)發(fā)生用戶(hù)方式的執(zhí)行。使用SuspendThread函數(shù)暫停線(xiàn)程應(yīng)該在確切知道目標(biāo)線(xiàn)程正在做什么情況下,并采取措施避免因暫停線(xiàn)程的運(yùn)行而帶來(lái)的問(wèn)題或死鎖,因?yàn)槿绻€(xiàn)程正試圖從堆棧中分配內(nèi)存,該線(xiàn)程會(huì)在該堆棧上設(shè)置鎖,當(dāng)其他線(xiàn)程訪(fǎng)問(wèn)該堆棧時(shí)將被停止,直到暫停線(xiàn)程的恢復(fù)。

Windows中不存在暫停或恢復(fù)進(jìn)程的概念,允許一個(gè)進(jìn)程暫停另一個(gè)進(jìn)程中所有線(xiàn)程的運(yùn)行,但從事暫停操作的進(jìn)程必須是個(gè)調(diào)試程序,也需要調(diào)用WaitForDebugEventContinueDebugEvent之類(lèi)的函數(shù)。總言,Windows沒(méi)有提供方法暫停進(jìn)程中的所有線(xiàn)程運(yùn)行。這里有一個(gè)作者寫(xiě)的暫停進(jìn)程函數(shù)作為要暫停進(jìn)程的參考用。

Void SuspendProcess(DWORD dwProcessID,BOOL fSuspend){

?????? //get the list of threads in the system

?????? HANDLE hSnapshot=CreateToolhelp32Snapshot(

?????????????????????????????????????????????????????????????? TH32CS_SNAPTHREAD,dwProcessID);

?????? if(hSnapshot != INVALID_HANDLE_VALUE){

????????????? //walk the list of threads

????????????? THREADENTRY32 te={sizeof(te)};

????????????? BOOL fOk=Thread32First(hSnapshot,&te);

????????????? for(;fOk;fOk=Thread32Next(hSnapshot,&te)){

???????????????????? //Is this thread in the desired process?

???????????????????? if(te.th32OwnerProcessID = = dwProcessID){

??????????????????????????? //attempt to convert the thread ID into a handle

??????????????????????????? HANLDE hThread=OpenThread(THREAD_SUSPEND_RESUME,FALSE,

??????????????????????????????????????????????????????????????????????????????????? te.th32ThreadID);

??????????????????????????? if(hThread!=NULL){

?????????????????????????????????? //suspend or resume the thread

?????????????????????????????????? if(fSuspend)

????????????????????????????????????????? SuspendThread(hThread);

?????????????????????????????????? Else

????????????????????????????????????????? ResumeThread(hThread);

??????????????????????????? }

??????????????????????????? CloseHandle(hThread);

???????????????????? }

????????????? }

????????????? CloseHandle(hSnapShot);

?????? }

}

該函數(shù)使用ToolHelp函數(shù)枚舉系統(tǒng)中的線(xiàn)程列表,當(dāng)找到作為指定進(jìn)程的組成部分的線(xiàn)程時(shí),就調(diào)用HANDLE OpenThread(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwThreadID)函數(shù)找出匹配線(xiàn)程ID的線(xiàn)程內(nèi)核對(duì)象,對(duì)內(nèi)核對(duì)象的使用計(jì)數(shù)進(jìn)行遞增,然后返回對(duì)象的句柄,運(yùn)用這個(gè)句柄可調(diào)用SuspendThreadResumeThread來(lái)暫停或恢復(fù)線(xiàn)程的運(yùn)行。

如果線(xiàn)程不想愛(ài)某個(gè)時(shí)間段被調(diào)度,可以調(diào)用Sleep函數(shù)來(lái)實(shí)現(xiàn):void sleep(DWORD dwMillisecondes),這個(gè)函數(shù)使線(xiàn)程暫停自己運(yùn)行,知道dwMillisecondes后,該函數(shù)需要注意的是:1)調(diào)用sleep函數(shù),使線(xiàn)程自愿放棄它的剩余時(shí)間片;2)系統(tǒng)將在大約的指定毫秒內(nèi)使線(xiàn)程不可調(diào)度;3)可為sleep函數(shù)的參數(shù)dwMillisecondes傳遞INFINITE,告訴系統(tǒng)永不調(diào)度該線(xiàn)程,這不提倡,最好讓線(xiàn)程退出,還原其堆棧和內(nèi)核對(duì)象;4)可將0傳遞給sleep,這樣調(diào)用線(xiàn)程將釋放剩余時(shí)間片,并迫使系統(tǒng)調(diào)度另一個(gè)線(xiàn)程。

函數(shù)BOOL SwitchToThread()可轉(zhuǎn)換到另一個(gè)線(xiàn)程。當(dāng)調(diào)用這個(gè)函數(shù)時(shí),系統(tǒng)查看是否存在一個(gè)迫切需要CPU時(shí)間的線(xiàn)程,如沒(méi)有,SwitchToThread就會(huì)立即返回,如果存在,SwitchToThread就對(duì)該線(xiàn)程進(jìn)行調(diào)度。這個(gè)函數(shù)允許一個(gè)需要資源的線(xiàn)程強(qiáng)制另一個(gè)優(yōu)先級(jí)較低、而目前卻擁有該資源的線(xiàn)程放棄該資源。如果調(diào)用SwitchToThread函數(shù)時(shí)沒(méi)有其他線(xiàn)程能夠運(yùn)行,則返回FALSE,否則返回非0值。與sleep函數(shù)相似,區(qū)別在于SwitchToThread允許優(yōu)先級(jí)較低的線(xiàn)程運(yùn)行,即使低優(yōu)先級(jí)線(xiàn)程迫切需要CPU時(shí)間,sleep也能夠立即對(duì)調(diào)用線(xiàn)程重新進(jìn)行調(diào)度。

要獲取線(xiàn)程的運(yùn)行時(shí)間需要調(diào)用GetThreadTimes函數(shù),這個(gè)返回線(xiàn)程得到的CPU時(shí)間數(shù)量。具體實(shí)現(xiàn)代碼如下:

#include <windows.h>

?

__int64 FileTimeToQuadWord(PFILETIME pft)

{

?????? return(Int64ShllMod32(pft->dwHighDateTime,32) | pft->dwLowDateTime);

}

?

int main(int argc, char* argv[])

{

?????? FILETIME ftKernelTimeStart,ftKernelTimeEnd;

?????? FILETIME ftUserTimeStart,ftUserTimeEnd;

?????? FILETIME ftDummy;

?????? __int64 qwKernelTimeElapsed,qwUserTimeElapsed,qwTotalTimeElapsed;

?

?????? //Get start times

?????? GetThreadTimes(GetCurrentThread(),&ftDummy,&ftDummy,&ftKernelTimeStart,&ftUserTimeStart);

?

?????? //perform complex algorithm here.

?????? //Get ending times.

?????? GetThreadTimes(GetCurrentThread(),&ftDummy,&ftDummy,&ftUserTimeEnd,&ftUserTimeEnd);

?

?????? //Get the elapsed kernel and user times by converting the start and end times form FILETIMEs

?????? //to quad words and then subtract the start times from the end times.

?????? qwKernelTimeElapsed=FileTimeToQuadWord(&ftKernelTimeEnd)-FileTimeToQuadWord(&ftKernelTimeStart);

?

?????? qwUserTimeElapsed=FileTimeToQuadWord(&ftUserTimeEnd)-FileTimeToQuadWord(&ftUserTimeStart);

?

?????? //Get total time duration by adding the kernel and user times.

?????? qwTotalTimeElapsed=qwKernelTimeElapsed+qwUserTimeElapsed;

?

?????? // the total elapsed time is in qwTotalTimeElapsed and display in console

?????? printf("The executing times of thread is %d /n",qwTotalTimeElapsed);

?????? //printf("Hello World!/n");

?????? return 0;

}

環(huán)境結(jié)構(gòu)使系統(tǒng)保留線(xiàn)程的狀態(tài),在下次線(xiàn)程擁有CPU時(shí),能夠回到上次中斷運(yùn)行的地方。Windows允許查看線(xiàn)程內(nèi)核對(duì)象的內(nèi)部情況,以便抓取它當(dāng)前的一組CPU寄存器,若要執(zhí)行該項(xiàng)操作,可調(diào)用GetThreadContext函數(shù):

BOOL GetThreadContext(HANDLE hThread,PCONTEXT pContext);

調(diào)用該函數(shù),只需指定一個(gè)CONTEXT結(jié)構(gòu),對(duì)某些標(biāo)志(該結(jié)構(gòu)中的ContextFlags成員)進(jìn)行初始化,指明想要收回那些寄存器,并將該結(jié)構(gòu)的地址傳遞給函數(shù),函數(shù)會(huì)將數(shù)據(jù)填入到所要求的成員中。在調(diào)用GetThreadContext函數(shù)前,應(yīng)調(diào)用SuspendThread,否則線(xiàn)程可能被調(diào)度,且線(xiàn)程的環(huán)境與所收回的不同。一個(gè)線(xiàn)程實(shí)際有兩個(gè)環(huán)境,一個(gè)是用戶(hù)方式,一個(gè)是內(nèi)核方式。GetThreadContext只能返回線(xiàn)程的用戶(hù)方式環(huán)境,如調(diào)用SuspendThread來(lái)停止線(xiàn)程的運(yùn)行,但該線(xiàn)程目前正運(yùn)行在內(nèi)核方式下,那么即使SuspendThread尚未暫停該線(xiàn)程的運(yùn)行,它的用戶(hù)方式仍然處于穩(wěn)定狀態(tài)。線(xiàn)程在恢復(fù)用戶(hù)方式之前,無(wú)法執(zhí)行更多的用戶(hù)方式代碼,因此可放心將線(xiàn)程視為處于暫停狀態(tài),GetThreadContext函數(shù)將能正常運(yùn)行。CONTEXT結(jié)構(gòu)的ContextFlags成員并不與任何CPU寄存器對(duì)應(yīng)。無(wú)論是何種CPU結(jié)構(gòu),該成員存在于CONTEXT結(jié)構(gòu)定義中。ContextFlags成員用于向GetThreadContext函數(shù)指明想要檢索那些寄存器。如想獲得線(xiàn)程的控制寄存器,可以用如下代碼:

//Create a CONTEXT structure.

?????? CONTEXT Context;

?????? //Tell the system that we are interested in only the control registers.

?????? Context.ContextFlags=CONTEXT_CONTROL;

?????? //Tell the system to get the registers associated with a thread.

?????? GetThreadContext(hThread,&Context);

在調(diào)用GetThreadContext之前,須對(duì)CONTEXT結(jié)構(gòu)中的ContextFlags成員進(jìn)行初始化,如想獲得線(xiàn)程的控制寄存器和整數(shù)寄存器,需要進(jìn)行下面的ContextFlags初始化:

Context.ContextFlags=CONTEXT_CONTROL | CONTEXT_INTEGER;

也可以獲得線(xiàn)程的所有重要的寄存器(Mcirosoft認(rèn)為最常用的寄存器):

Context.ContextFlags=CONTEXT_FULL;

當(dāng)GetThreadContext返回時(shí),可容易查看線(xiàn)程的任何寄存器值,要編寫(xiě)與CPU相關(guān)的代碼。Windows可修改CONTEXT結(jié)構(gòu)中的成員,然后通過(guò)SetThreadContext將新寄存器值放回線(xiàn)程的內(nèi)核對(duì)象中:

BOOL SetThreadContext(HANDLE hThread,CONST CONTEXT *pContext);

修改其環(huán)境的線(xiàn)程前應(yīng)先暫停線(xiàn)程,否則結(jié)果不得而知。下面的代碼是演示:

//Create a CONTEXT structure.

?????? CONTEXT Context;

?????? //stop the thead from running

?????? SuspendThread(hThread);

??????

?????? //Get the thread's control registers.

?????? Context.ContextFlags=CONTEXT_CONTROL;

?????? //Tell the system to get the registers associated with a thread.

?????? GetThreadContext(hThread,&Context);

?

?????? //Make the instruction pointer point to the address of your choice.

?????? //Here I've arbitrarily set the address instruction pointer to 0x00010000

#if defined(_ALPHA_)

?????? Context.Fir=0x00010000;

#elif defined(_X86_)

?????? Context.Eip=0x00010000;

#else

#error Module contains CPU-specific code;modify and recompile.

#endif

?

?????? //Set the thread's registers to reflect the changed values.

?????? //It's not really necessary to reset the ControlFlags memeber because it was set earlier.

?????? Context.ContextFlags=CONTEXT_CONTROL;

?????? SetThreadContext(hThread,&Context);

?

?????? //Resuming the thread will cause it to begin execution at address 0x00010000.

?????? RusumeThread(hThread);

如此處理,可能導(dǎo)致遠(yuǎn)程線(xiàn)程中的違規(guī),向用戶(hù)顯示未處理的異常消息框,同時(shí)遠(yuǎn)程進(jìn)程終止運(yùn)行。GetThreadContextSetThreadContext函數(shù)可以對(duì)線(xiàn)程進(jìn)行多方面控制,但要慎用。

線(xiàn)程被賦予不同的優(yōu)先級(jí),決定系統(tǒng)調(diào)度程序選擇調(diào)度哪個(gè)線(xiàn)程來(lái)運(yùn)行(使其擁有CPU)。每個(gè)線(xiàn)程都被賦予一個(gè)從0(最低)到31(最高)的優(yōu)先級(jí)號(hào)碼。當(dāng)系統(tǒng)引導(dǎo)時(shí),會(huì)創(chuàng)建一個(gè)特殊的線(xiàn)程,稱(chēng)為0頁(yè)線(xiàn)程,該線(xiàn)程被賦予優(yōu)先級(jí)為0,是整個(gè)系統(tǒng)中唯一的一個(gè)在優(yōu)先級(jí)0上運(yùn)行的線(xiàn)程。當(dāng)系統(tǒng)中沒(méi)有任何需要執(zhí)行操作時(shí),0頁(yè)線(xiàn)程負(fù)責(zé)將系統(tǒng)中的所有空閑RAM頁(yè)面置0Windows支持6個(gè)優(yōu)先級(jí)類(lèi):空閑、低于正常、正常、高于正常、高和實(shí)時(shí),一般程序都處在正常這個(gè)級(jí)別。Windows Explorer是在高優(yōu)先級(jí)上運(yùn)行的,大多數(shù)時(shí)間Explorer線(xiàn)程是暫停的,等待用戶(hù)按下操作鍵或點(diǎn)擊鼠標(biāo)按照時(shí)被喚醒。當(dāng)Explorer的線(xiàn)程處于暫停狀態(tài)時(shí),系統(tǒng)不分配CPU給它的線(xiàn)程,這樣次優(yōu)先級(jí)的線(xiàn)程可以得到調(diào)度。但一旦用戶(hù)有按鍵操作,系統(tǒng)就會(huì)喚醒Explorer線(xiàn)程,如果低優(yōu)先級(jí)線(xiàn)程正在運(yùn)行,系統(tǒng)會(huì)立即搶在這些線(xiàn)程之前讓Explorer的線(xiàn)程優(yōu)先運(yùn)行。應(yīng)該避免使用實(shí)時(shí)這個(gè)最高的優(yōu)先級(jí)類(lèi),因?yàn)樗赡芨缮娌僮飨到y(tǒng)任務(wù)的運(yùn)行,可能阻止必要的磁盤(pán)I/O信息和網(wǎng)絡(luò)信息的產(chǎn)生。

當(dāng)調(diào)用CreateProcess時(shí),fdwCreate參數(shù)可以傳遞需要的優(yōu)先級(jí)類(lèi)。可通過(guò)調(diào)用SetPriorityClass來(lái)改變優(yōu)先級(jí)類(lèi):

BOOL SetPriorityClass(HANDLE hProcess,DWORD fdwPriority);

該函數(shù)將hProcess標(biāo)識(shí)的優(yōu)先級(jí)改為fdwPriority參數(shù)中設(shè)定的值。由于該函數(shù)帶有一個(gè)進(jìn)程句柄,所以只要擁有進(jìn)程的句柄和足夠的訪(fǎng)問(wèn)權(quán),就可以改變系統(tǒng)中運(yùn)行的任何進(jìn)程的優(yōu)先級(jí)類(lèi)。檢索進(jìn)程的優(yōu)先級(jí)類(lèi)函數(shù):DWORD GetPriorityClass(HANDLE hProcess)。如果使用Start命令來(lái)啟動(dòng)程序,可以使用一個(gè)開(kāi)關(guān)來(lái)設(shè)定應(yīng)用程序的起始優(yōu)先級(jí),如在命令外殼輸入如下命令可使系統(tǒng)啟動(dòng)Calculator,并在開(kāi)始時(shí)按空閑優(yōu)先級(jí)來(lái)運(yùn)行它:

C:/>START /LOW CALC.EXE

Start命令還能識(shí)別/BELOWNORMAL/NORMAL/ABOVENORMAL/HIGT/REALTIME等開(kāi)關(guān),以便按它們各自的優(yōu)先級(jí)啟動(dòng)執(zhí)行一個(gè)應(yīng)用程序。當(dāng)然,一旦應(yīng)用程序啟動(dòng)運(yùn)行,可以通過(guò)調(diào)用SetPriorityClass函數(shù)改變自己的優(yōu)先級(jí)。

當(dāng)系統(tǒng)將線(xiàn)程分配給處理器時(shí),Windows2000使用軟親緣性來(lái)進(jìn)程操作,這意味著如果所有其他因素相同的話(huà),它將設(shè)法在它上次運(yùn)行的哪個(gè)處理器上運(yùn)行線(xiàn)程,讓線(xiàn)程留在單個(gè)處理器上,有助于重復(fù)使用仍然在處理器的內(nèi)存高速緩存中的數(shù)據(jù)。Windows2000允許設(shè)置進(jìn)程和線(xiàn)程的親緣性,可控制哪個(gè)CPU運(yùn)行某些線(xiàn)程,稱(chēng)為硬親緣性。計(jì)算機(jī)在引導(dǎo)時(shí),要確定機(jī)器中有多少個(gè)CPU可供使用。通過(guò)調(diào)用GetSystemInfo函數(shù),應(yīng)用程序可查詢(xún)機(jī)器中的CPU數(shù)量。按照默認(rèn)設(shè)置,任何線(xiàn)程都可以調(diào)度到這些CPU中的任何一個(gè)上去運(yùn)行。為限制在可用CPU的子集上運(yùn)行的單個(gè)進(jìn)程中的線(xiàn)程數(shù)量,可調(diào)用:

BOOL SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR dwProcessAffinityMask);

第一個(gè)參數(shù)hProcess用于指明影響的是哪個(gè)進(jìn)程;第二個(gè)參數(shù)dwProcessAffinityMask是位屏蔽,用于指明線(xiàn)程可以在那些CPU上運(yùn)行,如傳遞0x00000005(二進(jìn)制010102位是真值)表示該進(jìn)程中的線(xiàn)程可以在CPU0CPU2上運(yùn)行,但是不能愛(ài)CPU1CPU331上運(yùn)行。子進(jìn)程可以繼承進(jìn)程的親緣性。同時(shí)可通過(guò)下面函數(shù)返回進(jìn)程的親緣性屏蔽:

BOOL GetProcessAffinityMask(HANDLE hProcess,

???????????????????????????????????????????????? PDWORD_PTR pdwProcessAffinityMask,

???????????????????????????????????????????????? PDWORD_PTR pdwSystemAffinityMask);

傳遞親緣性屏蔽的進(jìn)程句柄,函數(shù)將填入pdwProcessAffinityMask變量,同時(shí)返回系統(tǒng)的親緣性屏蔽(pdwSystemAffinityMask指向的變量中)。系統(tǒng)的親緣性屏蔽用于指明系統(tǒng)的那個(gè)CPU能夠處理線(xiàn)程,進(jìn)程的親緣性始終是一個(gè)系統(tǒng)的親緣性屏蔽的正確子集。上面談到的是將進(jìn)程的多個(gè)線(xiàn)程限制到一組CPU上運(yùn)行,那么同樣可以設(shè)置將進(jìn)程中的一個(gè)線(xiàn)程限制到一組CPU上去運(yùn)行。如包含4個(gè)線(xiàn)程的進(jìn)程,在擁有4個(gè)CPU的計(jì)算機(jī)上運(yùn)行,如為線(xiàn)程中的一個(gè)線(xiàn)程(正在執(zhí)行非常重要的操作)增加某個(gè)CPU始終供它使用,則需要對(duì)其他三個(gè)線(xiàn)程限制不能在CPU0上運(yùn)行,而只能在CPU1CPU2CPU3上運(yùn)行。

通過(guò)調(diào)用SetThreadAffinityMask函數(shù),能為各個(gè)線(xiàn)程設(shè)置親緣性屏蔽:

DWORD_PTR SetThreadAffinityMask(HANDLE hThread,

DWORD_PTR dwThreadAffinityMask);

函數(shù)中hThread參數(shù)用于指明要限制的線(xiàn)程,dwThreadAffinityMask用于指明線(xiàn)程能夠運(yùn)行在那個(gè)CPU上,dwThreadAffinityMask是進(jìn)程親緣性的相應(yīng)子集,返回值是線(xiàn)程的前一個(gè)親緣性屏蔽。上面例子中將3個(gè)線(xiàn)程限制在CPU1CPU2CPU3上運(yùn)行的代碼:

//Thread 0 can only on CPU0.

SetThreadAffinityMask(hThread0,0x00000001);

//Threads1/2/3 run on CPUs 1/2/3

SetThreadAffinityMask(hThread1,0x0000000E);

SetThreadAffinityMask(hThread2,0x0000000E);

SetThreadAffinityMask(hThread3,0x0000000E);

?????????????????? 如非 2008-12-22

總結(jié)

以上是生活随笔為你收集整理的线程的调度、优先级和亲缘性——Windows核心编程学习手札系列之七的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产农村妇女毛片精品久久 | 性色av无码久久一区二区三区 | 嫩草综合| 少妇裸体挤奶汁奶水视频 | 国产十八熟妇av成人一区 | 精品一区视频 | 8x8ⅹ国产精品一区二区二区 | av亚洲在线| 欧美一区二区激情视频 | 欧美激情自拍偷拍 | 婷婷综合五月 | 国产黄色录相 | 欧美精品区 | 高清日韩欧美 | 国产亚洲精品久久久久久久 | 美女脱了裤子让男人桶 | 伊人啪啪网 | 久久亚洲私人国产精品va | 久久视频一区二区 | 国产jizz| 91av手机在线 | 麻豆小视频| 麻豆视频在线观看免费网站黄 | 亚洲区欧美区 | 最近最新最好看的2019 | 国产经典一区二区 | 亚洲国产精品成人无久久精品 | 天天舔天天操天天干 | 色五婷婷| 女性女同性aⅴ免费观女性恋 | 日本久操视频 | 国产精品99视频 | 国产91欧美 | 亚洲91色| 91麻豆国产在线观看 | 国产又粗又长 | 欧美多人猛交狂配 | 日韩中文在线视频 | 日韩av在线一区 | 国产在线一级片 | 色av吧| 骚虎视频在线观看 | 国产乱仑 | 久爱视频在线 | 久久成人精品视频 | 草草影院ccyycom | h在线免费 | 中文字幕Av日韩精品 | 欧美 日韩 国产 一区二区三区 | 高级毛片 | 精品视频入口 | 干干干日日日 | 欧美日本在线播放 | 黄视频在线观看免费 | 性欧美xxxx | 337p亚洲精品色噜噜狠狠 | 91岛国| 看了下面会湿的视频 | 91精品国产高清一区二区三密臀 | 国产成人无码www免费视频播放 | 98av视频 | 97精品一区二区视频在线观看 | 日日日日日日bbbbbb | 中文在线字幕免费观看 | 一级黄色短片 | 99热中文| 久久久av免费 | 欧美一区二区免费在线观看 | 玖玖在线视频 | 国产亚洲精品美女 | 亚洲第九十七页 | 国产一区不卡在线 | 黑鬼巨鞭白妞冒白浆 | 情欲超 | 噼里啪啦国语版在线观看 | 另类小说五月天 | 少妇欧美激情一区二区三区 | 国产一级大片在线观看 | 婷婷免费 | 依人成人综合网 | 欧美性受xxxx黑人猛交88 | 国产电影免费观看高清完整版视频 | 亚洲欧美乱综合图片区小说区 | 成人午夜视频精品一区 | 一对一色视频聊天a | 福利一区三区 | 国产男女视频在线观看 | 那里可以看毛片 | 天天鲁一鲁摸一摸爽一爽 | 精品麻豆视频 | 1000部av| 男女黄色网 | gv天堂gv无码男同在线观看 | 处女朱莉 | 波多野结衣中文字幕一区二区三区 | 亚洲精品字幕在线观看 | 日本老熟妇毛茸茸 | 大奶毛片 | 中文字幕大全 |