我在工程里使用以下函数给线程设置一个方便调试的名称
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;
void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
// Visit http://www.cppblog.com/sunicdavy for original article
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
}
__except(EXCEPTION_CONTINUE_EXECUTION)
{
int a =1;
}
}
使用期间一直正常. 随着工程需求变化,我需要频繁的将一个被命名的线程创建工作一段时间后马上结束释放资源并重新创建,出现了死锁问题
死锁总是发生在主线程的Sleep或者是SetEvent两个WindowsAPI函数. 而且仅仅在Visual Studio 2008里调试时会发生死锁,脱离调试环境一切正常.
我开始打日志调试, 结果发现死锁前能够正常创建线程,但是线程函数根本没有调用进入.之后就在主线程Sleep处死锁了.
由于SetThreadName没有使用正规的API接口,而是使用抛异常方式, 而且线程名称应该只在Visual Studio IDE中才能显示, MSDN对RaiseException的描述里也有说明可以使用WaitForDebugEvent接收应用程序抛得异常.因此可以推断是SetThreadName造成的问题. 屏蔽SetThreadName,测试通过