我在工程里使用以下函數(shù)給線程設(shè)置一個方便調(diào)試的名稱
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.shnenglu.com/sunicdavy for original article
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
}
__except(EXCEPTION_CONTINUE_EXECUTION)
{
int a =1;
}
}
使用期間一直正常. 隨著工程需求變化,我需要頻繁的將一個被命名的線程創(chuàng)建工作一段時間后馬上結(jié)束釋放資源并重新創(chuàng)建,出現(xiàn)了死鎖問題
死鎖總是發(fā)生在主線程的Sleep或者是SetEvent兩個WindowsAPI函數(shù). 而且僅僅在Visual Studio 2008里調(diào)試時會發(fā)生死鎖,脫離調(diào)試環(huán)境一切正常.
我開始打日志調(diào)試, 結(jié)果發(fā)現(xiàn)死鎖前能夠正常創(chuàng)建線程,但是線程函數(shù)根本沒有調(diào)用進(jìn)入.之后就在主線程Sleep處死鎖了.
由于SetThreadName沒有使用正規(guī)的API接口,而是使用拋異常方式, 而且線程名稱應(yīng)該只在Visual Studio IDE中才能顯示, MSDN對RaiseException的描述里也有說明可以使用WaitForDebugEvent接收應(yīng)用程序拋得異常.因此可以推斷是SetThreadName造成的問題. 屏蔽SetThreadName,測試通過