线程完成后影响调试的线程句柄有效性?

时间:2016-07-14 14:28:05

标签: c++ windows debugging exception

我只是想确保找到正确的东西。

显然,在调试器下运行时,在无效句柄上调用CloseHandle()将导致抛出异常。不确定此行为的记录位置,但Google上有多处提及。

嗯,我在调试时得到它,但没有理由让句柄无效。

基本上线程已启动,之后会检查它是否挂起

auto waitResult = WaitForSingleObject( hThread, 100 );
if ( waitResult == WAIT_TIMEOUT )
{
     // Handle hung thread stuff
     // This branch is not executed and shown only for completeness
}
else
{
    // Thread completed OK stuff
    // Just saves some stuff produced by the thread.
}

// some stuff omitted 

// just prior to procedure exit
if ( hThread != NULL )
{
    CloseHandle( hThread );
    // When running under a debugger, throws a 0xC0000008 here
    // waitResult happens to be zero when this is happening
}

现在我不希望句柄无效,因为我刚刚成功完成了WaitForSingleObject()

当线程终止定义的行为时,线程上的句柄变为无效吗? (如果再次使用句柄值,似乎有竞争条件的危险)?

当然,我可以用CloseHandle() / try包裹catch。但我想了解发生了什么。

我也不介意知道微软正式说这个CloseHandle()在调试时抛出一个0xC0000008。

1 个答案:

答案 0 :(得分:0)

基于Raymond Chen的评论,我调查了我使用的句柄是否无效,并且惊讶地发现Microsoft实际上说线程创建API _beginthread()实际上可以返回无效句柄或句柄另一个线程。

WaitOnSingleObject()似乎认为句柄没问题。但是,如果在等待期间关闭了线程句柄,Microsoft会对未定义的行为发出警告。所以,让我们留下未定义行为的可能性。

如果句柄的有效性很重要,Microsoft的线程文档建议使用_beginthreadex()而不是_beginthread()

雷蒙德通过注意到另一个部分说明了这一点 “_endthread会自动关闭线程句柄,而_endthreadex则不会。因此,当您使用_beginthread和_endthread时,不要通过调用Win32 CloseHandle API显式关闭线程句柄。此行为与Win32 ExitThread API不同。”