1. 程式人生 > >VC中使用SetThreadName引起的執行緒死鎖

VC中使用SetThreadName引起的執行緒死鎖

我在工程裡使用以下函式給執行緒設定一個方便除錯的名稱

    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,測試通過