29win32编程基础——线程控制
线程控制主要使用的函数
CreateThread(NULL,NULL,ThreadAdd1Proc,(LPVOID*)1,0,NULL);` //创建线程的方式 SuspendThread(hanThread); //挂起线程 ResumeThread(hanThread); //恢复线程 ExitThread(0x5); //参数是退出码,这个码是自己定的,等于一个退出标志,告诉操作系统,让操作系统结束当前线程,并清理堆栈空间
TerminateThread //告诉操作系统,让操作系统结束指定线程,不清理堆栈空间
WaitForSingle() //等待信号返回
GetExitCodeThread //获取线程退出码,
结束线程的方式:
1、ExitThread 同步函数,让操作系统去结束当前线程,同时等待线程的结束。当操作系统结束线程并清理当前线程的堆栈空间后,操作系统做完这些事返回这个函数,然后继续执行这个函数下边的代码
2、TerminateThread 异步函数,让操作系统去结束指定线程,不清理线程的堆栈空间,因为操作系统结束其他线程的时候,可能另外的线程会使用要结束线程的资源,因此微软这里设计的是不结束,
这个函数,告诉操作系统结束其他线程之后,直接继续执行后边的代码(这就是异步),而不会等待。因此一般这个函数会配合WaitForSingle使用,WaitForSingle会阻塞这等着操作系统结束线程后返回WaitForSingle(给这个函数发消息),这个函数收到消息后,继续执行后边的代码。
3、线程函数返回,即线程ThreadProc回调函数代码流程正常结束,正常执行完所有的代码,在ThreadProc结束之前,自己编写代码做各种回收资源的操作。
线程切换要使用CONTEXT
typedef struct _CONTEXT {
DWORD64 P1Home;
DWORD64 P2Home;
DWORD64 P3Home;
DWORD64 P4Home;
DWORD64 P5Home;
DWORD64 P6Home;
DWORD ContextFlags;
DWORD MxCsr;
WORD SegCs;
WORD SegDs;
WORD SegEs;
WORD SegFs;
WORD SegGs;
WORD SegSs;
DWORD EFlags;
DWORD64 Dr0;
DWORD64 Dr1;
DWORD64 Dr2;
DWORD64 Dr3;
DWORD64 Dr6;
DWORD64 Dr7;
DWORD64 Rax;
DWORD64 Rcx;
DWORD64 Rdx;
DWORD64 Rbx;
DWORD64 Rsp;
DWORD64 Rbp;
DWORD64 Rsi;
DWORD64 Rdi;
DWORD64 R8;
DWORD64 R9;
DWORD64 R10;
DWORD64 R11;
DWORD64 R12;
DWORD64 R13;
DWORD64 R14;
DWORD64 R15;
DWORD64 Rip;
union {
XMM_SAVE_AREA32 FltSave;
NEON128 Q[16];
ULONGLONG D[32];
struct {
M128A Header[2];
M128A Legacy[8];
M128A Xmm0;
M128A Xmm1;
M128A Xmm2;
M128A Xmm3;
M128A Xmm4;
M128A Xmm5;
M128A Xmm6;
M128A Xmm7;
M128A Xmm8;
M128A Xmm9;
M128A Xmm10;
M128A Xmm11;
M128A Xmm12;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
} DUMMYSTRUCTNAME;
DWORD S[32];
} DUMMYUNIONNAME;
M128A VectorRegister[26];
DWORD64 VectorControl;
DWORD64 DebugControl;
DWORD64 LastBranchToRip;
DWORD64 LastBranchFromRip;
DWORD64 LastExceptionToRip;
DWORD64 LastExceptionFromRip;
} CONTEXT, *PCONTEXT;
线程切换其实就是保存当前线程中的各种寄存器的值,然后再恢复的过程。
BOOL WINAPI GetThreadContext( __in HANDLE hThread, __inout LPCONTEXT lpContext );获取线程上下文信息
BOOL WINAPI SetThreadContext( __in HANDLE hThread, __in const CONTEXT* lpContext );//然后修改某个线程上下文中的值,例如EIP,改变执行路径。
然后再ResumeThread恢复线程

浙公网安备 33010602011771号