您的位置:首页 > 其它

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

2013-07-14 19:07 387 查看
关于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个问题:

1 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]);
}
}







                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息