windows執行緒Context
執行緒;作業系統會維護該執行緒的CPU暫存器的狀態,該結構為上下文結構。Context
執行緒建立時可以指定執行緒為暫停狀態,這樣作業系統在排程時便不會進行排程該執行緒。
當執行緒的執行壞境作出修改時,必須是執行緒成為可排程程序。ResumeThread如果該函式執行成功返回執行緒的前一個暫停計數。
每個執行緒核心物件都維護著一個CONTEXT結構,裡面儲存了執行緒執行的狀態,執行緒也就是eip。
使得CPU可以記得上次執行該執行緒執行到哪裡了,該從哪裡開始執行,該執行緒內部資料如何如何。
該結構是與CPU有關的,特定的CPU對應著特定的CONTEXT結構。
x86型別CPU對應的CONTEXT結構文件如下:
typedef struct _CONTEXT {
// The flag values within this flag control the contents of
// a CONTEXT record.
//
// If the context record is used as an input parameter, then
// for each portion of the context record controlled by a flag
// whose value is set, it is assumed that that portion of the
// context record contains valid context. If the context record
// is being used to modify a thread's context, only that
// portion of the thread's context will be modified.
//
// If the context record is used as an IN OUT parameter to capture
// the context of a thread, only those portions of the thread's
// context corresponding to set flags will be returned.
//
// The context record is never used as an OUT only parameter.
//
DWORD ContextFlags;
//
// This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
// set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
// included in CONTEXT_FULL.
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
// This section is specified/returned if the
// ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
FLOATING_SAVE_AREA FloatSave;
// This section is specified/returned if the
// ContextFlags word contains the flag CONTEXT_SEGMENTS.
//
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
//
// This section is specified/returned if the
// ContextFlags word contains the flag CONTEXT_INTEGER.
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
// This section is specified/returned if the
// ContextFlags word contains the flag CONTEXT_CONTROL.
DWORD Ebp;
DWORD Eip;
DWORD SegCs; // MUST BE SANITIZED
DWORD EFlags; // MUST BE SANITIZED
DWORD Esp;
DWORD SegSs;
//
// This section is specified/returned if the ContextFlags word
// contains the flag CONTEXT_EXTENDED_REGISTERS.
// The format and contexts are processor specific
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
} CONTEXT;
可見,該CONTEXT結構中,儲存著直接和CPU有關的資訊:
1、ContextFlags,在查詢的時候需要設定該欄位,表示查詢哪些其他的CONTEXT結構欄位。
2、除錯暫存器組
3、FLOATING_SAVE_AREA FloatSave —— 浮點暫存器
4、段暫存器
5、通用資料暫存器(整型暫存器)組
6、控制暫存器組——比如CS、BP、SP之類的儲存基址指標和堆疊指標、程式計數器。
7、BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION] —— 擴充套件暫存器組
可以查詢CONTEXT結構中的內容。如上所述,通過設定CONTEXT中的ContextFlags欄位,選擇要查詢的內容:
1、CONTEXT_DEBUG_REGISTERS,查詢調式暫存器
2、CONTEXT_FLOATING_POINT,查詢浮點暫存器
3、CONTEXT_SEGMENTS,查詢段暫存器
4、CONTEXT_INTEGER,查詢通用資料暫存器
5、CONTEXT_CONTROL,查詢控制暫存器組
6、CONTEXT_EXTENDED_REGISTERS,擴充套件暫存器組
在查詢之前,先呼叫SuspendThread函式暫停一個執行緒的執行,然後呼叫GetThreadContext函式取得CONTEXT結構中相關內容。
下面程式碼查詢一個執行緒的控制暫存器組資訊:
CONTEXT Context;
SuspendThread(hThread);
Context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hThread, &Context);
Context.Eip = 0x00010000;
Context.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(hThread, &Context);
ResumeThread(hThread);
也就是說執行緒也是一個結構體,只是在高2g的記憶體中,我們無法訪問,執行緒也就是eip,當20毫秒的時間片用完時,切換到其它執行緒,
當執行完時,在context結構中取出儲存的第一個執行緒執行結束時的狀態,繼續執行。
執行緒同步的方式
關鍵程式碼段 使用者方式 優點速度快 缺點 無法設定關鍵程式碼段的超時值
EnterCriticalSection LeaveCriticalSection 在使用之前需要宣告一個critical_section的結構
在使用結構之前必須先進行初始化操作InitializeCriticalSection
在不使用這個結構時使用deleteCriticalSection
當一個執行緒試圖進入另一個執行緒擁有的關鍵程式碼段時,呼叫執行緒就立即被置於等待狀態,意味著會從使用者態轉換為核心態,代價是十分大的,因此使用迴圈鎖。InitializeCriticalSectionAndSpinCount第二個引數為迴圈等待的次數,在單核處理器下該值無效。初始化操作失敗會出現STATUS_NO_MEMOR異常
4000 通常情況下建議使用CriticalSectionAndSpinCount