看《_beginthreadex和CreateThread的区别和联系》的补遗

来源:互联网 发布:js array lastindexof 编辑:程序博客网 时间:2024/05/17 20:12

关于CreateThread和_beginthreadex的讨论,由来已久,《_beginthreadex和CreateThread的区别和联系》的总结集大成。

这里对文中提到的《Win32 多线程的创建方法和基本使用》提到的_beginthreadex的一个不足,做一个补充。

原作者对这个不足,写了如下测试代码:

void __cdecl ThreadProc(void *para){    printf("sub thread started\n");    // TODO: Add your thread code here.    printf("sub thread finished\n");    _endthread(); // 可以省略,隐含会调用。}int main(int argc, char* argv[]){    DWORD threadID;    HANDLE hThread[10];    for(int i =0;i<10;i++)        hThread[i] = (HANDLE)_beginthread(ThreadProc,0,NULL);    WaitForMultipleObjects(10, hThread,TRUE,INFINITE); //无法同步所有线程!    for(int i = 0;i<10;i++) {        CloseHandle(hThread); // 问题    }}
先顺便指出其中2个问题:

CloseHandle(hThread),明显是打错了,应是CloseHandle(hThread[i])。

2 既然_endthread();已经调用了CloseHandle,所以再调用CloseHandle完全是多余,而且会出错:主线程运行了CloseHandle,但程序仍未结束,那么_endthread里面调用CloseHandle,会抛出异常。当然,也可以理解原作者为了指出错误而故意加上了这件代码。

最后,说明解决正常使用WaitForMultipleObjects等待线程结束的方法。
既然线程内部会自动CloseHandle掉该线程的句柄,所以不能再使用这个句柄作为等待参数,但我们可以通过OpenThread获取该线程的新句柄,作为WaitForMultipleObjects的等待参数。代码如下:

unsigned  __stdcall ThreadProc(void *para){//printf("sub thread started\n");TRACE0("sub thread started\n");// TODO: Add your thread code here.//printf("sub thread finished\n");TRACE0("sub thread finished\n");_endthread(); // 可以省略,隐含会调用。return 0;}void Test(){unsigned threadID[10] = {0};HANDLE hThread[10] = {0};for(int i =0;i<10;i++)_beginthreadex(NULL, 0, ThreadProc,NULL, CREATE_SUSPENDED, &threadID[i]);for(int i = 0;i<10;i++) {hThread[i] = OpenThread(THREAD_ALL_ACCESS, TRUE, threadID[i]);ResumeThread(hThread[i]);}TRACE0("waiting all threads finish\n");WaitForMultipleObjects(10, hThread,TRUE,INFINITE); for(int i = 0;i<10;i++) {CloseHandle(hThread[i]);}}


	
				
		
原创粉丝点击