在 Windows 7 上,线程似乎在 _endthreadex 挂起,并且超时的 Waitforsingleobject 没有信号



我需要您的帮助来解决桌面应用程序面临的随机挂起问题。

我们有一个在单例类中实现的线程,用于在循环中调用Beep和Sleep API。所以我们启动线程来调用这些,然后过一段时间,我们中断循环,在主线程中等待一个超时的单个对象,然后退出线程。就在从线程函数返回之前,我们调用_endthreadex。这里有个问题。现在我不知道_endthreadex是否失败,以及它是如何在超时后阻止waitforsingleobject发出信号的。该代码的实现与_beginthreadex的示例非常相似。正如我所说,它是随机发生的,而且发生在很少的机器上。

unsigned __stdcall SecondThreadFunc( void* pArguments )
{
printf( "In second thread...n" );
while( m_iBeepMode == iBEEPON )
{
Beep(600, 100);
Sleep(100);
}
//I added a logging here, which gets logged in hang case.
_endthreadex( 0 );
return 0;
}
int main()
{
HANDLE hThread;
unsigned threadID;
printf( "Creating second thread...n" );
// Create the second thread.
hThread = (HANDLE)_beginthreadex( NULL, 16384, &SecondThreadFunc, this, 0, &threadID );
// the below code is not exactly in the same method. We call it at a later time to stop the beep.
m_iBeepMode = BEEPOFF;
WaitForSingleObject( hThread, 10000 );
// Added a logging here, which doesn't get logged.
// Destroy the thread object.
CloseHandle( hThread );
}

您需要将m_iBeepMode设置为原子模式,以便在每次迭代时对其进行检查。目前,由于编译器可以看到该函数中的任何内容都不会更改m_iBeepMode,因此该条件很可能会被完全删除。

请注意,这曾经是volatile的领域,但atomic是更常用的解决方案。

最新更新