[英]c++11 std::mutex compiler error in Visual Studio 2012
[英]C++11 std::mutex in Visual Studio 2012 deadlock when locked from DllMain()
當從DllMain()
鎖定std::mutex
時,我看到std::mutex
出現死鎖。這是一個最小的DLL測試用例,它對我來說是個問題。 我的實際代碼執行互斥鎖,因為它使用成員函數,這些成員函數也可以在常規函數初始化期間使用。
我認為問題是在main()
線程的調用堆棧和調度程序產生的另一個線程(可能)之間出現了調度程序之間的死鎖。 死鎖似乎發生在main()
實際執行之前。
對於如何解決/解決死鎖問題,我將不勝感激。
簡單的DLL:
static void testFunc()
{
std::mutex mtx;
mtx.lock();
mtx.unlock();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
testFunc ();
break;
case DLL_THREAD_ATTACH:
testFunc ();
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
在死鎖點,該過程中有兩個線程:
Not Flagged > 6408 0 Main Thread Main Thread msvcr110d.dll!Concurrency::details::SchedulerBase::SchedulerBase Normal
Not Flagged 7600 0 Worker Thread ntdll.dll!_TppWaiterpThread@4() ntdll.dll!_NtDelayExecution@8 Normal
這是main()
線程的調用堆棧:
ntdll.dll!_NtWaitForKeyedEvent@16() Unknown
ntdll.dll!_TppWaitpSet@16() Unknown
ntdll.dll!_TppSetWaitInterrupt@12() Unknown
ntdll.dll!_RtlRegisterWait@24() Unknown
kernel32.dll!_RegisterWaitForSingleObject@24() Unknown
> msvcr110d.dll!Concurrency::details::SchedulerBase::SchedulerBase(const Concurrency::SchedulerPolicy & policy) Line 152 C++
msvcr110d.dll!Concurrency::details::ThreadScheduler::ThreadScheduler(const Concurrency::SchedulerPolicy & policy) Line 26 C++
msvcr110d.dll!Concurrency::details::ThreadScheduler::Create(const Concurrency::SchedulerPolicy & policy) Line 34 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::CreateWithoutInitializing(const Concurrency::SchedulerPolicy & policy) Line 276 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::GetDefaultScheduler() Line 650 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::CreateContextFromDefaultScheduler() Line 567 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::CurrentContext() Line 399 C++
msvcr110d.dll!Concurrency::details::LockQueueNode::LockQueueNode(unsigned int timeout) Line 616 C++
msvcr110d.dll!Concurrency::critical_section::lock() Line 1017 C++
msvcp110d.dll!mtx_do_lock(_Mtx_internal_imp_t * * mtx, const xtime * target) Line 65 C++
msvcp110d.dll!_Mtx_lock(_Mtx_internal_imp_t * * mtx) Line 144 C++
ConsoleApplicationDll.dll!std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) Line 68 C++
ConsoleApplicationDll.dll!std::_Mutex_base::lock() Line 43 C++
ConsoleApplicationDll.dll!testFunc() Line 16 C++
ConsoleApplicationDll.dll!DllMain(HINSTANCE__ * hModule, unsigned long ul_reason_for_call, void * lpReserved) Line 29 C++
ConsoleApplicationDll.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 508 C
ConsoleApplicationDll.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 472 C
ntdll.dll!_LdrpCallInitRoutine@16() Unknown
ntdll.dll!_LdrpRunInitializeRoutines@4() Unknown
ntdll.dll!_LdrpInitializeProcess@8() Unknown
ntdll.dll!__LdrpInitialize@8() Unknown
ntdll.dll!_LdrInitializeThunk@8() Unknown
第二個線程的調用棧很短:
> ntdll.dll!_NtDelayExecution@8() Unknown
ntdll.dll!__LdrpInitialize@8() Unknown
ntdll.dll!_LdrInitializeThunk@8() Unknown
編輯1:
WinDbg確認這是加載程序鎖定問題:
PRIMARY_PROBLEM_CLASS: APPLICATION_HANG_HungIn_LoaderLock
似乎總是在main()之前執行QueueUserAPC()
進行隊列初始化,但要在可怕的加載器鎖之外執行。 這看起來像解決我的問題。
編輯1
經過一些測試后,如果我從DllMain()
排隊APC,則APC方法似乎可以工作,但是如果我從類的靜態全局實例的ctor排隊APC,則APC方法不能工作。 IOW,對於我來說,並不是在所有可能的編譯器和構建模式組合中都統一使用APC。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.