創建線程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1, &a, 0, NULL);
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全屬性 通常爲NULL
SIZE_T dwStackSize, // 參數用於設定線程可以將多少地址空間用於它自己的堆棧
// 每個線程擁有它自己的堆棧
LPTHREAD_START_ROUTINE lpStartAddress, // 參數用於指明想要新線程執行的線程函數的地址
LPVOID lpParameter, // 線程函數的參數
// 在線程啓動執行時將該參數傳遞給線程函數
// 既可以是數字,也可以是指向包含其他信息的一個數據結構的指針
DWORD dwCreationFlags, // 0 創建完畢立即調度 CREATE_SUSPENDED創建後掛起
LPDWORD lpThreadId // 線程ID
);
1. 返回值:線程句柄,是void *類型
2. 線程句柄與線程ID的區別:
線程是由Windows內核負責創建與管理的,句柄相當於一個令牌,有了這個令牌就可以使用線程對象。
線程ID是身份證,唯一的,系統進行線程調度的時候要使用的。
線程操作函數:
1. 掛起線程:
::SuspendThread(hThread);
2. 恢復線程
::ResumeThread(hThread);
3. 終止線程:
方式一:
::ExitThread(DWORD dwExitCode); //同步的,之後的代碼就不會執行了。
方式二:
線程函數返回
方式三:
::TerminateThread(hThread,2); //異步的,會使用一個新的線程。
::WaitForSingleObject(hThread,INFINITE); //正因爲是異步的,所以之後的代碼也有可能會執行,所以要進行阻塞。
線程結束後堆棧不會被清理,因爲其他線程可能會使用到。
4. 判斷線程是否結束
BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode);
_CONTEXT結構體
在時間片切換時將寄存器中的值保存到_CONTEXT結構體中。
typedef struct _CONTEXT {
//
// The flags 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 threads context, then only that
// portion of the threads context will be modified.
//
// If the context record is used as an IN OUT parameter to capture
// the context of a thread, then 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 contians the flag CONTEXT_FLOATING_POINT.
//
FLOATING_SAVE_AREA FloatSave;
//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_SEGMENTS.
//
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
//
// This section is specified/returned if the
// ContextFlags word contians 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 contians 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;
//1. 掛起線程
SuspendThread(線程句柄); //這樣獲取的CONTEXT 纔有意義。
CONTEXT context
//2. 設置要獲取的類型
context.ContextFlags = CONTEXT_CONTROL; //CONTEXT_FULL是獲取除Debug寄存器外所有的,其他單獨或取的在文檔中每類寄存器前都有介紹。如果需要全部獲取 CONTEXT_FULL | Debug寄存器的標誌 即可。
//3. 獲取
BOOL ok = ::GetThreadContext(hThread,&context);
//4. 設置
context.Eip = 0x401000;
SetThreadContext(hThread,&context);