在線程內(nèi)核對(duì)象的內(nèi)部有一個(gè)值,用于指明線程的暫停計(jì)數(shù)。當(dāng)調(diào)用C r e a t e P r o c e s s或C r e a t e T h r e a d函數(shù)時(shí),就創(chuàng)建了線程的內(nèi)核對(duì)象,并且它的暫停計(jì)數(shù)被初始化為1。當(dāng)線程的暫停計(jì)數(shù)是0的時(shí)候,除非線程正在等待其他某種事情的發(fā)生,否則該線程就處于可調(diào)度狀態(tài)。
恢復(fù)線程,可以用將調(diào)用R e s u m e T h r e a d
并將C r e a t e T h r e a d函數(shù)時(shí)返回的線程句柄傳遞給它(或者是將傳遞給C r e a t e P r o c e s s的p p i P r o c I n f o參數(shù)指向的線程句柄傳遞給它):DWORD ResumeThread(HANDLE hThread);
當(dāng)創(chuàng)建線程時(shí),除了使用C R E AT E _ S U S P E N D E D外,也可以調(diào)用S u s p e n dT h r e a d函數(shù)來(lái)暫停線程的運(yùn)行:
DWORD SuspendThread(HANDLE hThread);
暫停和恢復(fù)進(jìn)程的運(yùn)行
對(duì)于Wi n d o w s來(lái)說(shuō),不存在暫停或恢復(fù)進(jìn)程的概念,因?yàn)檫M(jìn)程從來(lái)不會(huì)被安排獲得C P U時(shí)間。Wi n d o w s確實(shí)允許一個(gè)進(jìn)程暫停另一個(gè)進(jìn)程中的所有線程的運(yùn)行,但是從事暫停操作的進(jìn)程必須是個(gè)調(diào)試程序。特別是,進(jìn)程必須調(diào)用Wa i t F o r D e b u g E v e n t和C o n t i n u e D e b u g E v e n t之類的函數(shù)。
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.
????????????HANDLE?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í)現(xiàn)的,但是有的時(shí)候會(huì)出錯(cuò).
?睡眠方式線程也能告訴系統(tǒng),它不想在某個(gè)時(shí)間段內(nèi)被調(diào)度。這是通過(guò)調(diào)用S l e e p函數(shù)來(lái)實(shí)現(xiàn)的:
VOID Sleep(DWORD dwMilliseconds);
關(guān)于S l e e p函數(shù),有下面幾個(gè)重要問(wèn)題值得注意:
? 調(diào)用S l e e p,可使線程自愿放棄它剩余的時(shí)間片。
? 系統(tǒng)將在大約的指定毫秒數(shù)內(nèi)使線程不可調(diào)度。不錯(cuò),如果告訴系統(tǒng),想睡眠1 0 0 m s,那么可以睡眠大約這么長(zhǎng)時(shí)間,但是也可能睡眠數(shù)秒鐘或者數(shù)分鐘。記住, Wi n d o w s不是個(gè)實(shí)時(shí)操作系統(tǒng)。雖然線程可能在規(guī)定的時(shí)間被喚醒,但是它能否做到,取決于系統(tǒng)中還有什么操作正在進(jìn)行。
? 可以調(diào)用S l e e p,并且為d w M i l l i s e c o n d s參數(shù)傳遞I N F I N I T E。這將告訴系統(tǒng)永遠(yuǎn)不要調(diào)度該線程。這不是一件值得去做的事情。最好是讓線程退出,并還原它的堆棧和內(nèi)核對(duì)象。
? 可以將0傳遞給S l e e p。這將告訴系統(tǒng),調(diào)用線程將釋放剩余的時(shí)間片,并迫使系統(tǒng)調(diào)度另一個(gè)線程。但是,系統(tǒng)可以對(duì)剛剛調(diào)用S l e e p的線程重新調(diào)度。如果不存在多個(gè)擁有相同優(yōu)先級(jí)的可調(diào)度線程,就會(huì)出現(xiàn)這種情況。
轉(zhuǎn)換到另一個(gè)線程系統(tǒng)提供了一個(gè)稱為S w i t c h To T h r e a d的函數(shù),使得另一個(gè)可調(diào)度線程(如果存在能夠運(yùn)行):
當(dāng)調(diào)用這個(gè)函數(shù)的時(shí)候,系統(tǒng)要查看是否存在一個(gè)迫切需要C P U時(shí)間的線程。如果沒(méi)有線程迫切需要C P U時(shí)間,S w i t c h To T h r e a d就會(huì)立即返回。如果存在一個(gè)迫切需要C P U時(shí)間的線程,S w i t c h To T h r e a d就對(duì)該線程進(jìn)行調(diào)度(該線程的優(yōu)先級(jí)可能低于調(diào)用S w i t c h To T h r e a d的線程)。
線程的運(yùn)行時(shí)間
//Get?the?current?time?(start?time).
DWORD?dwStartTime?=?GetTickCount();

//Perform?complex?algorithm?here.

//Subtract?start?time?from?current?time?to?get?duration.
DWORD?dwElapsedTime?=?GetTickCount()?-?dwStartTime;

這個(gè)代碼做了一個(gè)簡(jiǎn)單的假設(shè):即它不會(huì)被中斷。但是,在搶占式操作系統(tǒng)中,永遠(yuǎn)無(wú)法知道線程何時(shí)被賦予C P U時(shí)間。
幸運(yùn)的是,Wi n d o w s提供了一個(gè)稱為G e t T h r e a d Ti m e s的函數(shù),它能返回這些信息:
BOOL GetThreadTimes(HANDLE hThread,
PFILETIME pftCreationTime, PFILETIME pftExitTime,
PFILETIME pftKernelTime, PFILETIME pftUserTime);
使用實(shí)例
__int64?FileTimeToQuadWord(PFILETIME?pft)?


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

void?PerformLongOperation()?


{
???FILETIME?ftKernelTimeStart,?ftKernelTimeEnd;
???FILETIME?ftUserTimeStart,???ftUserTimeEnd;

???FILETIME?ftDummy;
???__int64?qwKernelTimeElapsed,?qwUserTimeElapsed,
??????qwTotalTimeElapsed;

???//Get?starting?times.
???GetThreadTimes(GetCurrentThread(),?&ftDummy,
??????&ftDummy,?&ftKernelTimeStart,?&ftUserTimeStart);

???//Perform?complex?algorithm?here.

???//Get?ending?times.
???GetThreadTimes(GetCurrentThread(),?&ftDummy,
??????&ftDummy,?&ftKernelTimeEnd,?&ftUserTimeEnd);

???//Get?the?elapsed?kernel?and?user?times?by?
???//converting?the?start?and?end?times?
???//from?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.
}

注意,G e t P r o c e s s Ti m e s是個(gè)類似G e t T h r e a d Ti m e s的函數(shù),適用于進(jìn)程中的所有線程:
BOOL GetProcessTimes(HANDLE hProcess,
PFILETIME pftCreationTime, PFILETIME pftExitTime,
PFILETIME pftKernelTime, PFILETIME pftUserTime);
對(duì)于高分辨率的配置文件來(lái)說(shuō), G e t T h r e a d Ti m e s并不完美。Wi n d o w s確實(shí)提供了一些高分辨率性能函數(shù):
BOOL QueryPerformanceFrequency(
LARGE_INTEGER* pliFrequency);
BOOL QueryPerformanceCounter(
LARGE_INTEGER* pliCount);
雖然這些函數(shù)認(rèn)為,正在執(zhí)行的線程并沒(méi)有得到搶占的機(jī)會(huì),但是高分辨率的配置文件是為短期存在的代碼塊設(shè)置的。為了使這些函數(shù)運(yùn)行起來(lái)更加容易一些,我創(chuàng)建了下面這個(gè)C + +類:
class?CStopwatch?


{
public:
???CStopwatch()?

???
{?
??????QueryPerformanceFrequency(&m_liPerfFreq);
??????Start();
???}

???void?Start()?

???
{?
??????QueryPerformanceCounter(&m_liPerfStart);
???}

???__int64?Now()?const?

???
{
??????//Returns?#?of?milliseconds?since
??????//Start?was?called

??????LARGE_INTEGER?liPerfNow;
??????QueryPerformanceCounter(&liPerfNow);

??????return?(((liPerfNow.QuadPart?-?
?????????m_liPerfStart.QuadPart)?*?1000)/
?????????m_liPerfFreq.QuadPart);
???}

private:

???//Counts?per?second
???LARGE_INTEGER?m_liPerfFreq;???

???//Starting?count
???LARGE_INTEGER?m_liPerfStart;??
};

使用這個(gè)類如下:(這樣的封裝類很多的,我的blog有介紹)
//Create?a?stopwatch?timer
//(which?defaults?to?the?current?time).
CStopwatch?stopwatch;

//Execute?the?code?I?want?to?profile?here.

//Get?how?much?time?has?elapsed?up?to?now.
??__int64?qwElapsedTime?=?stopwatch.Now();

//qwElapsedTime?indicates?how?long?
//the?profiled?code?executed?in?milliseconds.

運(yùn)用結(jié)構(gòu)環(huán)境(跟cpu的類型有關(guān)系)
環(huán)境結(jié)構(gòu)使得系統(tǒng)能夠記住線程的狀態(tài),這樣,當(dāng)下次線程擁有可以運(yùn)行的C P U時(shí),它就能夠找到它上次中斷運(yùn)行的地方。
Wi n d o w s實(shí)際上允許查看線程內(nèi)核對(duì)象的內(nèi)部情況,以便抓取它當(dāng)前的一組C P U寄存器。若要進(jìn)行這項(xiàng)操作,只需要調(diào)用G e t T h r e a d C o n t e x t函數(shù):
BOOL GetThreadContext(HANDLE hThread,
PCONTEXT pContext);
Wi n d o w s使你能夠修改C O N T E X T結(jié)構(gòu)中的成員,然后通過(guò)調(diào)用S e t T h r e a d C o n t e x t將新寄存器值放回線程的內(nèi)核對(duì)象中:
BOOL SetThreadContext(HANDLE hThread,
CONST CONTEXT *pContext);
線程的優(yōu)先級(jí)
若要設(shè)置和獲得線程的相對(duì)優(yōu)先級(jí),必須調(diào)用下面的這些函數(shù):
BOOL SetThreadPriority(HANDLE hThread,
int nPriority);
下面是檢索線程的相對(duì)優(yōu)先級(jí)的補(bǔ)充函數(shù):
int GetThreadPriority(HANDLE hThread);
程序的優(yōu)先級(jí)(進(jìn)程的優(yōu)先級(jí))
下面是如何使一個(gè)進(jìn)程將它自己的優(yōu)先級(jí)類設(shè)置為空閑的例子:
BOOL SetPriorityClass(GetCurrentProcess(),
IDLE_PRIORITY_CLASS);
下面是用來(lái)檢索進(jìn)程的優(yōu)先級(jí)類的補(bǔ)充函數(shù):
DWORD GetPriorityClass(HANDLE hProcess);
動(dòng)態(tài)提高線程的優(yōu)先級(jí)等級(jí)
有些編程人員抱怨說(shuō),系統(tǒng)動(dòng)態(tài)提高線程優(yōu)先級(jí)等級(jí)的功能對(duì)他們的線程性能會(huì)產(chǎn)生一種不良的影響,為此M i c r o s o f t增加了下面兩個(gè)函數(shù),這樣就能夠使系統(tǒng)的動(dòng)態(tài)提高線程優(yōu)先級(jí)等級(jí)的功能不起作用:
BOOL SetProcessPriorityBoost(HANDLE hProcess,
BOOL DisablePriorityBoost);
BOOL SetThreadPriorityBoost(HANDLE hThread,
BOOL DisablePriorityBoost);
這兩個(gè)函數(shù)具有許多相似的共性,可以用來(lái)確定是激活還是停用優(yōu)先級(jí)提高功能:
BOOL GetProcessPriorityBoost(HANDLE hProcess,
PBOOL pDisablePriorityBoost);
BOOL GetThreadPriorityBoost(HANDLE hThread,
PBOOL pDisablePriorityBoost);
為前臺(tái)進(jìn)程調(diào)整調(diào)度程序(windows設(shè)置提供可以自定義優(yōu)先執(zhí)行application或后臺(tái)的server)