线程操作
// classcode.cpp : Defines the entry point for the application. // #include "stdafx.h" #include<stdio.h> #include "resource.h" HANDLE hThread1; HWND hEdit ; DWORD WINAPI ThreadProc1(LPVOID lpParameter) { TCHAR szBuffer[10]; DWORD dwIndex = 0; DWORD dwCount; while(dwIndex<10000) { GetWindowText(hEdit,szBuffer,10); sscanf( szBuffer, "%d", &dwCount ); dwCount++; memset(szBuffer,0,10); sprintf(szBuffer,"%d",dwCount); Sleep(1000); SetWindowText(hEdit,szBuffer); dwIndex++; } return 0; } BOOL CALLBACK MainDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { BOOL bRet = FALSE; switch(uMsg) { case WM_CLOSE: { EndDialog(hDlg,0); break; } case WM_INITDIALOG: { hEdit = GetDlgItem(hDlg,IDC_EDIT1); SetWindowText(hEdit,"0"); break; } case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_BUTTON_T1: { hThread1 = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL); return TRUE; } case IDC_BUTTON_T2: { SuspendThread(hThread1); return TRUE; } case IDC_BUTTON3: ResumeThread(hThread1); return TRUE; return TRUE; case IDC_BUTTON4: ::TerminateThread(hThread1,2); ::WaitForSingleObject(hThread1,INFINITE); return TRUE; } break ; } return bRet; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDlgProc); return 0; }
挂起线程:
::SuspendThread(hThread);
恢复线程:
::ResumeThread(hThread);
终止线程:
方式一:
::ExitThread(DWORD dwExitCode); //销毁线程堆栈,但不销毁堆
方式二:
线程函数返回
方式三:
::TerminateThread(hThread,2); //此函数异步执行,并且线程堆栈不被销毁,可用于程序其他部分使用数据,其中2位退出码
::WaitForSingleObject(hThread,INFINITE); //此函数在指定线程没有结束的时候将当前线程阻塞,直到指定线程结束为止 ,这个时候其后跟的代码才安全
判断线程是否结束
BOOL GetExitCodeThread(
HANDLE hThread,
LPDWORD lpExitCode
);
STILL_ACTIVE 正在运行
参数:
hThread: 要结束的线程句柄
dwExitCode: 指定线程的退出代码。可以通过GetExitCodeThread来查看一个线程的退出代码
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;
获取线程CONTEXT结构:
//挂起线程
SuspendThread(线程句柄);
CONTEXT context
//设置要获取的类型
context.ContextFlags = CONTEXT_CONTROL;
//获取
BOOL ok = ::GetThreadContext(hThread,&context);
//设置
context.Eip = 0x401000;
SetThreadContext(hThread,&context);