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恢复线程
posted @ 2023-10-31 16:16  一日学一日功  阅读(72)  评论(0)    收藏  举报