線程內(nèi)核對(duì)象中有個(gè)叫做掛起計(jì)數(shù)的東西
每次調(diào)用CreateProcess或者CreateThread時(shí)
這個(gè)東西就會(huì)在線程內(nèi)核對(duì)象創(chuàng)建后初始化為1
然后在線程初始化完成前 就不會(huì)被調(diào)度了
然后在初始化之后 CreateProcess和CreateThread會(huì)檢查有沒(méi)有CREATE_SUSPENDED標(biāo)志傳入
有的話函數(shù)就會(huì)將這個(gè)線程掛起 沒(méi)有則掛起計(jì)數(shù)會(huì)變0
然后線程就可以被調(diào)度了
對(duì)于處于掛起狀態(tài)的線程 我們可以在線程執(zhí)行任何代碼前改變它的環(huán)境(如優(yōu)先級(jí))
然后就是把線程變成可調(diào)度的的方法:
調(diào)用ResumeThread函數(shù) 傳入線程句柄
成功將返回線程的前一個(gè)掛起計(jì)數(shù) 失敗則返回0xFFFFFFFF
一個(gè)線程可以多次掛起 掛起多少次就要Resume多少次才能調(diào)度
DWORD ResumeThread(HANDLE hThread);
另外還可以通過(guò)SuspendThread函數(shù)來(lái)掛起線程
DWORD SuspendThread(HANDLE hThread);
這個(gè)函數(shù)的返回值和ResumeThread相同
(一個(gè)線程最多可以掛起MAXIMUM_SUSPEND_COUNT次[WinNT.h中定義為127])
進(jìn)程的掛起和恢復(fù)(并不存在的概念)
這是一個(gè)掛起進(jìn)程中所有線程的問(wèn)題
雖然沒(méi)有現(xiàn)成的比較好的函數(shù)
但是我們可以自己寫(xiě)一個(gè)
VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend) {
HANDLE hThreadSnapShot = INVALID_HANDLE_VALUE;
THREADENTRY32 te32 = {sizeof(te32)};
hThreadSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
if (hThreadSnapShot != INVALID_HANDLE_VALUE) {
Thread32First(hThreadSnapShot, &te32);
do {
if (te32.th32OwnerProcessID == dwProcessID) {
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
if (hThread != NULL) {
if (fSuspend) {
SuspendThread(hThread);
}else{
ResumeThread(hThread);
}
}
CloseHandle(hThread);
}
}while (Thread32Next(hThreadSnapShot, &te32));
CloseHandle(hThreadSnapShot);
}
}
線程還可以干一件叫做睡眠的事情 大概就是一段時(shí)間內(nèi)不接受調(diào)度的(傲嬌)行為
VOID Sleep(DWORD dwMilliseconds);
具體作用就是會(huì)停止dwMilliseconds ms的時(shí)間
如果傳入0的話 其實(shí)就是強(qiáng)制系統(tǒng)去調(diào)用另外一個(gè)線程(然后這個(gè)線程還可以調(diào)度 嗯標(biāo)準(zhǔn)傲嬌)
切換到另一個(gè)線程的方法:
使用函數(shù)SwitchToThread()
這是一個(gè)并沒(méi)有參數(shù)的函數(shù)
所以有必要解釋一下調(diào)用時(shí)會(huì)發(fā)生什么:
首先系統(tǒng)會(huì)查看是否存在急需CPU時(shí)間的饑餓進(jìn)程
- 沒(méi)有:立即返回
- 有:調(diào)度這個(gè)線程
那么這個(gè)函數(shù)和Sleep(0)的作用的區(qū)別在哪兒呢= =
答案是 Sleep(0)之后系統(tǒng)會(huì)運(yùn)行優(yōu)先級(jí)最高的線程
SwitchToThread允許運(yùn)行優(yōu)先級(jí)比自己低的線程
有時(shí)候需要計(jì)算線程運(yùn)行的時(shí)間
一般的做法(誤):
ULONGLONG qwStartTime = GetTickCount64();
...(somethings needed to do)
ULONGLONG qwElapsedTime = GetTickCount64() - qwStartTime;
這樣做表面看并沒(méi)有問(wèn)題 但問(wèn)題是windows是個(gè)搶占式的系統(tǒng)
所以析显。贱迟。就會(huì)坑
于是你需要使用
BOOL GetThreadTimes (
HANDLE hThread,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime
);