HANDLE CreateThread(
_In_opt_
LPSECURITY_ATTRIBUTES lpThreadAttributes,
//SECURITY_ATTRIBUTES结构指定了这个线程的安全属性,如果填NULL则就以默认的安全描述子创建,并且返回的句柄不会被继承。
_In_SIZE_T dwStackSize,
//线程的堆栈大小(单位是字节),如果为0则默认和主线程一样大。堆栈再进程的内存空间内自动分配并在进程结束时释放。如有必要堆栈大小可以增加。
//CreateThread在试图分配大小为dwAtackSize字节数的内存,并在可用内存不足时返回失败消息。
_In_LPTHREAD_START_ROUTINE lpStartAddress,
//指向线程所需要执行的应用程序提供的函数,同时这也代表线程开始的地址。函数接受一个32位的参数并返回一个32位值
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
//指定一个传递给线程的32位参数值
_In_DWORD dwCreationFlags,
//指定一个附加标志来控制线程的创建。如果CREATE_SUSPENDED标志被定义,线程就以挂起状态创建,即直到ResumeThread()函数被调用之前都不执行
//如果该值为0,线程在创建后立即开始执行
_Out_opt_ LPDWORD lpThreadId
//指向一个保存线程的ID,32位变量
)
如果执行成功,其返回值是指向下一个新线程的句柄。如果失败,将返回NULL。
当执行完一个线程后,应该关闭该线程的句柄。CloseHandle(),该函数使用CreateThread()返回点句柄,并将对应内核对象的引用计数器加减1。
这并不是强制关闭一个线程,而是告诉系统改线程处于结束时运行状态。
BOOL CloseHandle( _In_ HANDLE hObject )成功返回true,否者false
测试代码1当线程循环的次数小于主线程次数时
#include <windows.h> #include <iostream> using namespace std; DWORD WINAPI Print_Thread(LPVOID data) { cout<<"开始线程\n"; for(int index=0;index<25; index++)//循环25次 { cout<<"Thread_"<<(int)data<<"_"<<index<<"\n"; Sleep(100); } cout<<"Print_Thread线程执行完毕\n"; return (DWORD)data; } int main() { HANDLE threadHandle;//声明一个句柄 DWORD threadID;//线程ID threadHandle=CreateThread( NULL, 0, Print_Thread, (LPVOID)1, 0, &threadID ); for (int index=0;index<50; index++)//循环50次 { cout<<"Start_2_"<<index<<"\n"; Sleep(100); } CloseHandle(threadHandle); system("pause"); return 0; } 测试代码2当线程循环的次数大于主线程次数时 #include <windows.h> #include <iostream> using namespace std DWORD WINAPI Print_Thread(LPVOID data) { cout<<"开始线程\n"; for(int index=0; index<50;index++)//循环50次 { cout<<"Thread_"<<(int)data<<"_"<<index<<"\n"; Sleep(100); } cout<<"Print_Thread线程执行完毕\n"; return (DWORD)data; } int main() { HANDLE threadHandle;//声明一个句柄 DWORD threadID;//线程ID threadHandle=CreateThread( NULL, 0, Print_Thread, (LPVOID)1, 0, &threadID ); for (int index=0; index<25;index++)//循环25次 { cout<<"Start_2_"<<index<<"\n"; Sleep(100); } CloseHandle(threadHandle); system("pause"); return 0; }
只看看代码1可能没有什么特别的发现,所以我写了代码2与其进行对比。细心的读者会发现我只是改了主线程和子线程for循环的次数。
对比两个代码你会发现,当主线程结束时,子线程还在继续,由于我加了system("pause");所以第一个主线程的for循环结束后,程序没有直接退出,然而我们才能看到子线程还在继续跑直到结束才停止。如果你将system("pause");你会发现,当主线程执行完后程序直接退出,不会等待子线程结束。