阻塞线程

WaitForSingleObject

等待, 直到指定的对象处于发信号状态或超时间隔过去。

  1. DWORD WaitForSingleObject(
  2. HANDLE hHandle, // 要等待的对象句柄
  3. DWORD dwMilliseconds, // 最多等待的毫秒数,如果参数为INFINITE(-1),则没有超时限制
  4. );

如果对象句柄是一个 互斥体(Mutex) 或 互斥类事件(event), 则 WaitForSingleObject()执行后,会使信号值-1
如果函数成功,则返回值指示导致函数返回的事件。此值可以是以下值之一:

  • WAIT_OBJECT_0 发出指定对象的状态信号。
  • WAIT_ABANDONED 指定的对象是互斥对象,在拥有线程终止之前,拥有互斥对象的线程未释放该互斥对象。互斥对象的所有权授予调用线程,并且互斥设置为无信号。
  • WAIT_IO_COMPLETION 一个或多个I / O完成例程排队等待执行。
  • WAIT_TIMEOUT 超时间隔已经过去,并且对象的状态未信号化。

如果函数失败,则返回-1。

WaitForMultipleObjects

等待指定的多个线程执行

  1. DWORD WaitForMultipleObjects(
  2. DWORD nCount, // 线程句柄数组的大小
  3. CONST HANDLE *lpHandles, // 线程句柄数组指针
  4. BOOL fWaitAll, // 等待模式: TRUE,则所有线程状态变化才返回; FALSE,则只要一个线程状态发生变化就返回
  5. DWORD dwMilliseconds // 最多等待的毫秒数,如果参数为INFINITE(-1),则没有超时限制
  6. );

调用示例:

  1. HANDLE arrThread[2];
  2. arrThread[0] = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
  3. arrThread[1] = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
  4. WaitForMultipleObjects(2,arrThread,TRUE,-1);
  5. cout << "所有线程执行完毕" << endl;

获取线程退出码

GetExitCodeThread

获取指定线程的返回值

  1. BOOL GetExitCodeThread(
  2. HANDLE hThread, // 线程句柄
  3. [OUT] LPDWORD lpExitCode // 接收线程返回值的地址
  4. );

调用示例:

  1. // 创建两个线程的代码 略
  2. WaitForMultipleObjects(2, arrThread, TRUE, -1);
  3. DWORD dwResult1;
  4. GetExitCodeThread(arrThread[0], dwResult1);

创建线程

在windows上, 创建线程的函数有两个, CreateThread()和_beginthreadex()
在Linux上, 创建线程的函数有一个, pthread_create()

CreateThread(不推荐)

创建一个在本进程的地址空间中执行的线程
CreateThread函数是Windows提供的用于创建线程的函数

  1. HANDLE CreateThread(
  2. LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性, 一般为NULL
  3. DWORD dwStackSize, // 线程的栈空间大小, 单位为Byte。一般为0, 表示使用默认大小
  4. LPTHREAD_START_ROUTINE lpStartAddress, // 指向线程函数的指针, 调用方式必须为__stdcall
  5. LPVOID lpParameter, // 指定传递给线程的32位参数值。
  6. DWORD dwCreationFlags, // 指定控制线程创建的附加标志。如果该值为NULL,则线程在创建后立即运行。如果为CREATE_SUSPENDED,则线程将以挂起状态创建,并且在调用ResumeThread函数之前不会运行。
  7. LPDWORD lpThreadId // 指向接收线程标识符tid的DWORD指针。如果该参数为NULL,则不返回线程标识符TID。
  8. );

返回值:

  • 成功,则返回新线程的句柄。
  • 失败返回NULL

    _beginthreadex(推荐)

    Windows CRT(C Runtime)库提供的创建线程的函数, 底层是调用CreateThread, 更安全, 推荐使用
    使用前需#include <process.h>
    1. DWORD _beginthreadex(
    2. void *security, // 安全属性, 0
    3. unsigned stack_size, // 堆栈大小, 0
    4. unsigned ( __stdcall *start_address )( void * ), // 回调函数
    5. void *arglist, // 参数列表的指针
    6. unsigned initflag, // 创建标志
    7. unsigned *thrdaddr // 接收TID的指针
    8. );

创建远程线程

CreateRemoteThread

创建一个在其它进程地址空间运行的线程

  1. HANDLE CreateRemoteThread(
  2. HANDLE hProcess, // 远程线程所属进程的进程句柄.
  3. LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指定了线程的安全属性.NULL
  4. DWORD dwStackSize, // 线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
  5. LPTHREAD_START_ROUTINE lpStartAddress, // 在远程进程的地址空间中,已经存在的线程函数的起始地址.
  6. LPVOID lpParameter, // 传给线程函数的参数.
  7. DWORD dwCreationFlags, // 线程的创建标志.
  8. LPDWORD lpThreadId // 返回的TID的指针
  9. );

返回值:

  • 如果函数成功,则返回值是新线程的句柄。
  • 失败返回NULL

调用示例:

  1. HANDLE hProcess, hThread;
  2. DWORD dwPid;
  3. // 1.获取进程ID
  4. HWND hwnd = FindWindow(L"类名",L"标题");
  5. GetWindowThreadProcessId(hwnd, &dwPid);
  6. // 2.获取进程句柄
  7. hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
  8. // 3.创建远程线程
  9. hThread = CreateRemoteThread(hProcess, NULL, 0,
  10. (LPTHREAD_START_ROUTINE)0x00401000, // 在远程进程内存空间中的函数首地址
  11. NULL, 0, NULL);
  12. // 4.等待远程线程执行完毕
  13. WaitForSingleObject(hThread, -1);
  14. // 5.关闭句柄
  15. CloseHandle(hProcess);
  16. CloseHandle(hThread);