win32相关(创建线程)
创建线程
什么是线程?
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位,一个进程可以包含多个线程,但一个进程至少包含一个线程
基本概念
- 轻量级进程: 线程比进程更轻量,创建和销毁的开销更小
- 共享资源: 同一进程内的多个线程共享进程的内存空间和系统资源
- 独立执行流: 每个线程有自己的程序计数器、寄存器集合和栈
// 创建线程
#include <iostream>
#include <windows.h>using namespace std;DWORD WINAPI ThreadProce(LPVOID lpParameter) {cout << "helloWorld\n";return 0;
}int main() {HANDLE hThread = CreateThread(NULL, NULL, ThreadProce, NULL, NULL, NULL);system("pause");return 0;
}
CreateThread函数参数
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全描述符SIZE_T dwStackSize, // 设置堆栈的大小如为NULL则默认为1MBLPTHREAD_START_ROUTINE lpStartAddress, // 指向由线程执行的应用程序定义函数的指针LPVOID lpParameter, // 指向要传递给线程的变量的指针DWORD dwCreationFlags, // 控制线程创建的标志 (0:创建后,线程会立即运行 CREATE_SUSPENDED:线程以挂起状态创建,在调用 ResumeThread 函数之前不会运行 STACK_SIZE_PARAM_IS_A_RESERVATION:dwStackSize 参数 指定堆栈的初始保留大小。 如果未指定此标志,dwStackSize 指定提交大小)LPDWORD lpThreadId // 指向接收线程标识符的变量的指针。 如果此参数 NULL,则不返回线程标识符
);
线程状态
线程有激发态(有信号状态)和非激发态(无信号状态)之分,正在运行的线程处于非激发态,线程结束就会处于激发状
WaitForSingleObject
函数就是等待线程处于激发态
DWORD WaitForSingleObject(HANDLE hHandle, // 线程句柄DWORD dwMilliseconds // 要等待的时间(毫秒),如果要一直等待则为INFINITE
);
当主线程结束时,子线程就算还未结束,子线程也会一起挂掉
线程相关API
- CreatedThread 创建
- OpenThread 打开
- ExitThread 退出
- TerminateThread 结束
- SuspendThread 暂停
- ResumeThread 恢复
- GetExitCodeThread 得到线程的执行结果
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>using namespace std;int main() {// 获取进程的线程列表HANDLE hThreadList = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);THREADENTRY32 threadInfo{ sizeof(THREADENTRY32) };BOOL isSucess = Thread32First(hThreadList, &threadInfo);if (isSucess) {do {if (threadInfo.th32OwnerProcessID == 28440) {// 是不是画图的进程cout << "线程ID:" << threadInfo.th32ThreadID << endl;HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,NULL,threadInfo.th32ThreadID);//SuspendThread(hThread); // 挂起ResumeThread(hThread); // 恢复}} while (Thread32Next(hThreadList, &threadInfo));}system("pause");return 0;
}
注:由于每个线程有自己的程序计数器、寄存器集合和栈,那它是怎么在切换时,知道每个寄存器当前的值的呢?答案是每一个线程都有一个上下文结构体,当它切换的时候都会把它的数据保存到这个结构体当中 CONTEXT (上下文)
设置获取线程上下文
// 获取线程上下文
BOOL GetThreadContext(HANDLE hThread,LPCONTEXT lpContext
);
// 设置线程上下文
BOOL SetThreadContext(HANDLE hThread;CONST CONTEXT *lpContext
);DWORD WINAPI ThreadProce(LPVOID lpParameter) {cout << "helloWorld\n";return 0;
}int main(){HANDLE hThread = CreateThread(NULL, NULL, ThreadProce, NULL, NULL, NULL);CONTEXT context; // 线程上下文结构体context.ContextFlags = CONTEXT_INTEGER;GetThreadContext();
}