1.如何让线程停下来?
相应函数: | |
让自己停下来: Sleep()函数 让别人停下来(挂起): SuspendThread()函数 线程恢复: ResumeThread()函数 |
一个线程挂起几次,就需要恢复几次;
2.等待线程结束
- WaitForSingleObject(); WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。
#include "stdafx.h" #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 100; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 0; } int main() { HANDLE hThread; hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); //线程传递参数直接传递地址就行了,可以传任何类型的指针,结构体等等; WaitForSingleObject(hThread, INFINITE);//对象被触发信号后,函数才会返回。 printf("如果上面线程的信号不发生变化,不会执行我 "); getchar(); return 0; }
- WaitForMultipleObjects(); //等待多个线程当WaitForMultipleObjects等到多个内核对象的时候,如果它的bWaitAll 参数设置为false。其返回值减去WAIT_OBJECT_0 就是参数lpHandles数组的序号。如果同时有多个内核对象被触发,这个函数返回的只是其中序号最小的那个。如果为TRUE 则等待所有信号量有效再往下执行。(FALSE 当有其中一个信号量有效时就向下执行)
-
#include "stdafx.h" #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 100; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 0; } int main() { HANDLE hThreadArr[2]; hThreadArr[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); //线程传递参数直接传递地址就行了,可以传任何类型的指针,结构体等等; hThreadArr[1] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); WaitForMultipleObjects(2, hThreadArr,TRUE, INFINITE);//参数一:几个线程;参数二:线程数组;参数三:是否两个都执行完后才放开阻塞;参数四:等待模式 printf("如果上面线程的信号不发生变化,不会执行我 "); getchar(); return 0; }
- GetExitCodeThread();
获取线程运行的返回值,可以通过这个来判断是否线程运行成功
// 线程创建.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 100; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParameter) { for (int i = 0; i < 100; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 1; } int main() { HANDLE hThreadArr[2]; DWORD dwResult1; DWORD dwResult2; hThreadArr[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); //线程传递参数直接传递地址就行了,可以传任何类型的指针,结构体等等; hThreadArr[1] = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL); WaitForMultipleObjects(2, hThreadArr,TRUE, INFINITE);//参数一:几个线程;参数二:线程数组;参数三:是否两个都执行完后才放开阻塞;参数四:等待模式 GetExitCodeThread(hThreadArr[0],&dwResult1); GetExitCodeThread(hThreadArr[1], &dwResult2); printf("如果上面线程的信号不发生变化,不会执行我 "); getchar(); CloseHandle(hThreadArr[0]); CloseHandle(hThreadArr[1]); return 0; }
线程上下文:
CONTEXT 结构;//本质一堆寄存器;
设置获取线程上下文函数:(单核CPU怎么跑多线程的原理)
BOOL GetThreadContext(HANDLE hThread,LPCONTEXT lpContext);
BOOL SetThreadContext(HANDLE hThread,CONST CONTEXT* lpContext);
// 线程创建.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 1; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParameter) { for (int i = 0; i < 1; i++) { Sleep(50); printf("++++++++++++++++++%d ", i); } return 1; } int main() { HANDLE hThreadArr[2]; DWORD dwResult1; DWORD dwResult2; hThreadArr[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); //线程传递参数直接传递地址就行了,可以传任何类型的指针,结构体等等; hThreadArr[1] = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL); SuspendThread(hThreadArr[0]);//获取线程上下文一定要先把线程挂起 CONTEXT context; //设置一个CONTEXT结构体 context.ContextFlags = CONTEXT_INTEGER; //ContextFlags需要哪些寄存器就直接填写哪些 GetThreadContext(hThreadArr[0], &context); printf("%x %x ", context.Eax, context.Ebp); ResumeThread(hThreadArr[0]); //恢复线程运行 getchar(); CloseHandle(hThreadArr[0]); CloseHandle(hThreadArr[1]); return 0; }