Windows核心程式設計筆記(七) 執行緒排程 優先順序 關聯性
在搶佔式多工作業系統中,執行緒的執行是有限制的,系統會排程一個執行緒在一個時間塊內佔用CPU,在時間到了之後將執行緒的上下文(CONTEXT結構,儲存執行緒切換前的CPU個暫存器的值)儲存到執行緒核心物件中,從另一個可排程執行緒的CONTEXT中獲取屬於它的CPU各暫存器的值,設定CPU暫存器,執行該執行緒,這樣重複著在不同的執行緒之間切換,保證每個可排程執行緒能得到執行時間。
在我使用的64位WIN7中 GetSystemTimeAdjustment
DWORD SuspendThread(HANDLE hThread ); 返回執行緒上次掛起的次數
掛起一個執行緒,一個執行緒最多可以掛起, 一個執行緒最多可以掛起MAXIMUM_SUSPEND_COUNT (127)次, 被掛起的執行緒不參與執行緒排程
DWORD ResumeThread(HANDLE hThread ); 返回上次掛起次數
遞減執行緒核心物件中 執行緒掛起計數,只有在掛起減到0時,執行緒才能恢復執行
程序不能掛起,除了在偵錯程式處理WaitForDebugEvent時,被除錯的程序所有執行緒會掛起。
Sleep函式
1、呼叫Sleep函式使執行緒掛起,執行緒放棄剩餘的時間片
2、Sleep設定的掛起時間只是近似值,不保證會準時醒來
3、可以傳入INFINITE執行緒永久掛起
4、傳入0表示放棄當前使用的剩餘時間片
SwitchToThread 讓出時間片,可能排程給比自己優先順序低的執行緒
可以在一段程式碼的之前使用GetThreadTime獲取執行緒執行的時間,取前後時間的差 做為該段程式碼的執行時耗。
在VISTA中為執行緒分配CPU時間的方式發生了變化 ,在新的系統中使用處理器時間戳計時器TSC,線上程被排程程式暫停時,將計算此時TSC的值與執行緒開始時的TSC值之間的差,然後線上程執行時間上加上該差值,不計算中斷時間。我們可以使用ReadTimeStampCounter巨集來獲取TSC的值。
GetThreadContext 獲取執行緒的上下文,這裡CONTEXT結構對熟悉彙編的看起來會很親切。Windwos 還是提供了SetThreadContext函式,這是很強大的對於喜歡做一些比較另類和猥瑣的事情的人,比如可以建立一個掛起的程序比如系統的計算器,把另一個執行檔案,比如系統的記事本程式自己載入到這個掛起的程序空間中去,然後改變主執行緒的CONTEXT,設定成記事本程式主執行緒入口所需要的環境,那麼就可以借屍還魂了。在工作管理員裡看到的是一個計算器程式,實際執行的程式碼是記事本的。
執行緒的優先順序
在Windows中執行緒的優先順序為0-31,優先順序高的執行緒優先被排程,只有在優先順序高的執行緒都處於不可排程狀態時,才遞減排程其次優先順序的執行緒,當較高優先順序的執行緒佔用了CPU時間,致使較低優先順序的執行緒無法執行時成為飢餓,在多處理器上飢餓的情況發生的可能性很小,系統大多數執行緒都是不可排程的,例如執行緒呼叫了GetMessage等待獲取訊息,如果這時訊息佇列中沒有訊息,系統會暫停這個執行緒,並將CPU分配給另一個等待排程的執行緒。
在較低優先順序的執行緒被排程時,如果有較高優先順序的執行緒已經處於可排程狀態,系統會暫停較低優先順序的執行緒,將CPU分給高優先順序的執行緒,Windows的執行緒排程是搶佔掠奪式的。
Windwos的程序優先順序分為6個等級,可以通過SetPriorityClass來設定
BOOL WINAPI SetPriorityClass(
__in HANDLE hProcess,
__in DWORD dwPriorityClass
);
dwPriorityClass對應的標誌實際優先順序值
優先順序 | 標誌 | 優先順序值 |
idle (低) | IDLE_PRIORITY_CLASS | 4 |
Below (低於標準) | BELOW_NORMAL_PRIORITY_CLASS | |
normal (標準) | NORMAL_PRIORITY_CLASS | 7或9 |
Above (高於標準) | ABOVE_NORMAL_PRIORITY_CLASS | |
high (高) | HIGH_PRIORITY_CLASS | 13 |
realtime (實時) | REALTIME_PRIORITY_CLASS |
24 |
Windwos的執行緒有6個相對於程序的優先順序,相對優先順序使用 SetThreadPriority來設定
BOOL WINAPI SetThreadPriority(
__in HANDLE hThread,
__in int nPriority
);
nPriority對應的標誌在程序優先順序的基礎上調整
執行緒優先順序等級 | 標誌 | 優先順序值 |
idle (最低) | THREAD_PRIORITY_IDLE | 如果程序優先順序為realtime則調整為16,其它情況為1 |
LOWEST 低 | THREAD_PRIORITY_LOWEST | -2(在原有基礎上-2) |
BELOW 低於標準 | THREAD_PRIORITY_BELOW_NORMAL | -1(在原有基礎上-1) |
NORMAL(標準) | THREAD_PRIORITY_NORMAL | 不變(取程序優先順序值) |
ABOVE 高於標準 | THREAD_PRIORITY_ABOVE_NORMAL | +1(在原有基礎上+1) |
HIGHEST(高) | THREAD_PRIORITY_HIGHEST | +2(在原有基礎上+2) |
CRITICAL(最高) | THREAD_PRIORITY_TIME_CRITICAL | 如果程序優先順序為realtime則調整為31,其它情況為15 |
這些程序優先順序和執行緒相對優先順序在Windwos不同版本 所對應的優先順序值得對映不有變化的。
當一個程序中的執行緒為了響應某種IO事件,比如視窗訊息,磁碟讀取,獲取網路包,執行緒會在這時被系統動態提升為NORMAL級,且只能提升1~15級的執行緒。線上程提升優先順序後的每個時間片內優先順序會被遞減,直到恢復原來的優先順序。
可以使用SetProcessPriority 來設定是否允許系統動態提升執行緒優先順序。使用GetProcessPriority來獲取執行緒是否開啟被提升。
排程IO請求優先順序
在設定程序和執行緒優先順序時可以為 這兩個函式傳入 對應的THREAD_MODE_BACKGROUND_BEGIN PROCESS_MODE_BACKGROUND_BEGIN 讓執行緒或程序進入低IO優先順序狀態,傳入THREAD_MODE_BACKGROUND_END PROCESS_MODE_BACKGROUND_END 進入NORMAL級狀態。
CPU關聯性
我們可以使用下滿兩個函式設定執行緒或程序運行於哪個CPU之上。dwProcessAffinityMask 用二進位制位做掩碼,比如3 程式碼執行在CPU0和CPU1上,5表示在CPU2和CPU0上
BOOL WINAPI SetProcessAffinityMask(
__in HANDLE hProcess,
__in DWORD_PTR dwProcessAffinityMask
);
DWORD_PTR WINAPI SetThreadAffinityMask(
__in HANDLE hThread,
__in DWORD_PTR dwThreadAffinityMask
);
相關推薦
Windows核心程式設計筆記(七) 執行緒排程 優先順序 關聯性
在搶佔式多工作業系統中,執行緒的執行是有限制的,系統會排程一個執行緒在一個時間塊內佔用CPU,在時間到了之後將執行緒的上下文(CONTEXT結構,儲存執行緒切換前的CPU個暫存器的值)儲存到執行緒核心物件中,從另一個可排程執行緒的CONTEXT中獲取屬於它的CPU各暫存器
Windows核心程式設計筆記(5)----執行緒排程,優先順序
1、作業系統執行緒排程過程 每個執行緒都有一個上下文CONTEXT結構體,儲存線上程的核心物件中,這個上下文中儲存了執行緒上一次執行時CPU暫存器的狀態。每隔固定時間,Windows會檢視所有當前存在的執行緒核心物件,其中只有一些是可排程的。Windows在可排程的執行緒中
《自己動手寫java虛擬機器》學習筆記(七)-----執行緒私有執行時資料區(go)
專案地址:https://github.com/gongxianshengjiadexiaohuihui 在執行java程式時,Java虛擬機器需要使用記憶體來存放各種各樣的資料,Java虛擬機器規範把這些記憶體的區
Windows核心程式設計筆記(二十) 視窗與訊息2
喚醒一個執行緒 執行緒的掛起與喚醒 (1)當執行緒呼叫GetMessage或WaitMessage,而訊息佇列中又沒有訊息出現時,執行緒會被掛起。 (2)當訊息被“Post”(也可以是執行緒間的“Send”)到訊息佇列時,相應的Wake標誌位會被設定,以表明該執行緒
Windows核心程式設計筆記(十八) SEH結構化異常 二
23.2 編譯器層面對系統SEH機制的封裝 23.2.1 擴充套件的EXCEPTION_REGISTRATION級相關結構:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTION_REGISTRATION結構 struct VC_EX
Java併發程式設計的藝術筆記(八)——執行緒池
一.執行緒池的主要處理流程 ThreadPoolExecutor執行execute方法分下面4種情況。 1)如果當前執行的執行緒少於corePoolSize,則建立新執行緒來執行任務(注意,執行這一步需要獲取全域性鎖)。 2)如果執行的執行緒等於或多於corePoolSize,則將任
程式設計師面試寶典隨筆記(一)---執行緒和程序1,-基礎資訊
①程式,程序,執行緒的區別 程式:程式是由一系列的指令和邏輯組成的一個靜態檔案(如cpp檔案),無論能不能執行,它都客觀的存在於儲存器中。 程序:程序是計算機中的程式關於某資料集合
CUDA學習筆記(2)- 執行緒並行和塊並行
1. 獲取顯示卡裝置資訊 有些顯示卡支援CUDA有些不支援,那麼如何確定主機的顯示卡裝置是否支援CUDA呢。可以使用下面的函式獲取顯示卡的相關資訊。 cudaError_t cudaGetDeviceCount(int *count) 獲取支援CUD
C#學習筆記(11)- 執行緒類與程序類
為什麼要使用多執行緒? 讓計算機“同時”做多件事情,節約時間 多執行緒可以讓一個程式“同時”處理多個事情 後臺執行程式,提高程式的執行效率,也不會使主介面出現無響應的情況 獲得當前執行緒與當前程序 前臺執行緒與後臺執行緒 前臺執行緒:只有所
JUC學習筆記(2)—執行緒間通訊
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; cla
Python學習總結筆記(4)--執行緒區域性變數之Threading.local
當我們使用執行緒的時候,能使用執行緒的區域性變數,就儘量不要用全域性變數,因為使用全域性變數涉及同步的問題(參見我的上一篇部落格Python學習總結筆記(3)–多執行緒與執行緒同步 )。 使用區域性變數的時候,需要傳遞引數,比如有這樣一個例子,程式需要處理客戶
Java 多執行緒(七)——執行緒組與執行緒池
1 執行緒組 1.1 概述 Java中使用ThreadGroup來表示執行緒組,它可以對一批執行緒進行分類管理。對執行緒組的控管理,即同時控制執行緒組裡面的這一批執行緒。 使用者建立的所有執行緒都屬於指定執行緒組,如果沒有顯示指定屬於哪個執行緒組,那麼
安卓學習筆記(一)——執行緒的用法及怎樣在子執行緒中更新UI
建立執行緒方法: 1、新建一個繼承自Thread的類MyThread,然後重寫父類的run()方法,在裡面寫要執行的內容; class MyThread extends Thread { @Ove
Java併發程式設計實戰(5)- 執行緒生命週期
在這篇文章中,我們來聊一下執行緒的生命週期。 [toc] # 概述 執行緒是作業系統中的一個概念,在Java中,它是實現併發程式的主要手段。 Java中的執行緒,本質上就是作業系統中的執行緒。 作業系統中的執行緒有“生老病死”,專業說法就是生命週期,雖然不同的開發語言對於作業系統的執行緒做了不同的封裝
執行緒與多執行緒(四)——執行緒排程
四、執行緒排程 執行緒排程管理器負責執行緒排隊和CPU線上程間的分配,並按執行緒排程演算法進行排程。當執行緒排程管理器選中某個執行緒時,該執行緒獲得 CPU資源進人執行狀態。 執行緒排程是搶佔式排程,即如果在當前執行緒執行過程中個更高優先順序的執行緒
嵌入式核心及驅動開發之學習筆記(七) 非阻塞模式+中斷實現讀取資料
當中斷髮生時,驅動程式會跳轉到中斷處理的函式入口,實現了中斷的捕獲和處理,但這樣還不夠。要讓使用者能夠獲取到中斷分析的結果,我們將建立一個描述中斷事件的結構體物件。硬體產生中斷後,驅動程式碼將對中斷事件的分析結果儲存在結構體變數中,使用者需要的時候,直接通過介面函式獲取這個結構體的資料。 核心層
java 併發程式設計學習筆記(七)FutureTask, ForkJoin, BlockingQueue
(1)Future 、FutureTask public class FutureExample { static class MyTask implements Callable<String> { @Override pu
各種音視訊編解碼學習詳解之 編解碼學習筆記(七):微軟Windows Media系列
最近在研究音視訊編解碼這一塊兒,看到@bitbit大神寫的【各種音視訊編解碼學習詳解】這篇文章,非常感謝,佩服的五體投地。奈何大神這邊文章太長,在這裡我把它分解成很多小的篇幅,方便閱讀。大神部落格傳送門:https://www.cnblogs.com/skyofbitbi
學習筆記(七)多執行緒開發
相信大家在Java中都已經接觸過執行緒,就是像一條線一樣一次執行相關的操作,特點就是同步的,順序進行的。 但是,Android和Java的執行緒有一點區別在於就是在子執行緒中不能對UI元件進行相關操作,Android中的所有元件的操作要求在主執行緒(UI執行緒