阻塞线程
WaitForSingleObject
等待, 直到指定的对象处于发信号状态或超时间隔过去。
DWORD WaitForSingleObject(
HANDLE hHandle, // 要等待的对象句柄
DWORD dwMilliseconds, // 最多等待的毫秒数,如果参数为INFINITE(-1),则没有超时限制
);
如果对象句柄是一个 互斥体(Mutex) 或 互斥类事件(event), 则 WaitForSingleObject()执行后,会使信号值-1
如果函数成功,则返回值指示导致函数返回的事件。此值可以是以下值之一:
- WAIT_OBJECT_0 发出指定对象的状态信号。
- WAIT_ABANDONED 指定的对象是互斥对象,在拥有线程终止之前,拥有互斥对象的线程未释放该互斥对象。互斥对象的所有权授予调用线程,并且互斥设置为无信号。
- WAIT_IO_COMPLETION 一个或多个I / O完成例程排队等待执行。
- WAIT_TIMEOUT 超时间隔已经过去,并且对象的状态未信号化。
WaitForMultipleObjects
等待指定的多个线程执行
DWORD WaitForMultipleObjects(
DWORD nCount, // 线程句柄数组的大小
CONST HANDLE *lpHandles, // 线程句柄数组指针
BOOL fWaitAll, // 等待模式: TRUE,则所有线程状态变化才返回; FALSE,则只要一个线程状态发生变化就返回
DWORD dwMilliseconds // 最多等待的毫秒数,如果参数为INFINITE(-1),则没有超时限制
);
调用示例:
HANDLE arrThread[2];
arrThread[0] = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
arrThread[1] = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
WaitForMultipleObjects(2,arrThread,TRUE,-1);
cout << "所有线程执行完毕" << endl;
获取线程退出码
GetExitCodeThread
获取指定线程的返回值
BOOL GetExitCodeThread(
HANDLE hThread, // 线程句柄
[OUT] LPDWORD lpExitCode // 接收线程返回值的地址
);
调用示例:
// 创建两个线程的代码 略
WaitForMultipleObjects(2, arrThread, TRUE, -1);
DWORD dwResult1;
GetExitCodeThread(arrThread[0], dwResult1);
创建线程
在windows上, 创建线程的函数有两个, CreateThread()和_beginthreadex()
在Linux上, 创建线程的函数有一个, pthread_create()
CreateThread(不推荐)
创建一个在本进程的地址空间中执行的线程
CreateThread函数是Windows提供的用于创建线程的函数
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性, 一般为NULL
DWORD dwStackSize, // 线程的栈空间大小, 单位为Byte。一般为0, 表示使用默认大小
LPTHREAD_START_ROUTINE lpStartAddress, // 指向线程函数的指针, 调用方式必须为__stdcall
LPVOID lpParameter, // 指定传递给线程的32位参数值。
DWORD dwCreationFlags, // 指定控制线程创建的附加标志。如果该值为NULL,则线程在创建后立即运行。如果为CREATE_SUSPENDED,则线程将以挂起状态创建,并且在调用ResumeThread函数之前不会运行。
LPDWORD lpThreadId // 指向接收线程标识符tid的DWORD指针。如果该参数为NULL,则不返回线程标识符TID。
);
返回值:
- 成功,则返回新线程的句柄。
- 失败返回NULL
_beginthreadex(推荐)
Windows CRT(C Runtime)库提供的创建线程的函数, 底层是调用CreateThread, 更安全, 推荐使用
使用前需#include <process.h>
DWORD _beginthreadex(
void *security, // 安全属性, 0
unsigned stack_size, // 堆栈大小, 0
unsigned ( __stdcall *start_address )( void * ), // 回调函数
void *arglist, // 参数列表的指针
unsigned initflag, // 创建标志
unsigned *thrdaddr // 接收TID的指针
);
创建远程线程
CreateRemoteThread
创建一个在其它进程地址空间运行的线程
HANDLE CreateRemoteThread(
HANDLE hProcess, // 远程线程所属进程的进程句柄.
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指定了线程的安全属性.NULL
DWORD dwStackSize, // 线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
LPTHREAD_START_ROUTINE lpStartAddress, // 在远程进程的地址空间中,已经存在的线程函数的起始地址.
LPVOID lpParameter, // 传给线程函数的参数.
DWORD dwCreationFlags, // 线程的创建标志.
LPDWORD lpThreadId // 返回的TID的指针
);
返回值:
- 如果函数成功,则返回值是新线程的句柄。
- 失败返回NULL
调用示例:
HANDLE hProcess, hThread;
DWORD dwPid;
// 1.获取进程ID
HWND hwnd = FindWindow(L"类名",L"标题");
GetWindowThreadProcessId(hwnd, &dwPid);
// 2.获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
// 3.创建远程线程
hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)0x00401000, // 在远程进程内存空间中的函数首地址
NULL, 0, NULL);
// 4.等待远程线程执行完毕
WaitForSingleObject(hThread, -1);
// 5.关闭句柄
CloseHandle(hProcess);
CloseHandle(hThread);