Вопрос в том, как строится статика на уровне функций, когда функция вызывается в нескольких потоках?
Описание проблемы: возникает тупик, и мое приложение не закрывается. Во время инициализации локальной статической переменной он пытается получить MSVCR80! _Lock и никогда не захватывает блокировку.
Команда
! Locks в WinDbg дает следующий вывод.
CritSec ntdll! LdrpLoaderLock + 0 при 7c97e178
LockCount 0
RecursionCount 1
OwningThread 1998
EntryCount d
ContentionCount d
*** Заблокировано
CritSec MSVCR80! __ app_type + 94 при 781c3bc8
LockCount 1
RecursionCount 1
OwningThread 9a8
EntryCount 1
ContentionCount 1
*** Заблокировано
Ниже приведен стек вызовов, и вы увидите, что он никогда не захватит блокировку _mlock
#
**
Стек вызовов Thread 17e8
**
781c3bc8 78132bd9 0777fde4 ntdll! RtlEnterCriticalSection + 0x46
00000008 b87d2630 00000000 MSVCR80! _Lock + 0x2e
0864ae10 08631d7f 0864ae10 EPComUtilities32! _Onexit + 0x36
0864ae10 b87d2588 00000001 EPComUtilities32! Atexit + 0x9
0777fea8 0864719f 08630000 EPComUtilities32! XCriticalSectionEx :: ThreadTermination + 0x5f
08630000 00000003 00000000 EPComUtilities32! DllMain + 0x20
08630000 7c90118a 08630000 EPComUtilities32! __DllMainCRTStartup + 0x7a
08630000 00000003 00000000 EPComUtilities32! _DllMainCRTStartup + 0x1d
#
**
вызов стека потока 1100
**
000000b0 00000000 00000000 ntdll! ZwWaitForSingleObject + 0xc
000000b0 ffffffff 00000000 kernel32! WaitForSingleObjectEx + 0xa8
000000b0 ffffffff 06ce64e0 kernel32! WaitForSingleObject + 0x12
000480ba 000f4240 00000000 CATSysMultiThreading! CATThreads :: Join + 0xf5
0012fcc8 00000004 00000000 JS0GROUP! CATLM :: StopHB + 0xf4
d138509f 00416694 00000001 JS0GROUP! CATLM :: Unmake + 0x6b
00000000 00000000 00000000 MSVCR80! _Cinit + 0xd6
00000000 0012fd6c 081e68d9 MSVCR80! Выход + 0xd
00000000 06d404f0 0998fb90 JS0GROUP! CATExit + 0x1d
00000000 004ef366 0000000d DNBPLMProvider! DNBEPLMTransactionMgt :: OnApplicationExit + 0x229
00000000 0012fd9c 004eabfc JS0GROUP! CATCallExits + 0x2bc
00000000 0012ff7c 0040cefd JS0GROUP! CATErrorNormalEnd + 0x31 00000000 06ce71d0 06ce71d0 JS0GROUP! CATExit + 0xc
00000007 06cdb120 059b61d8 DLMMfgContextSolver! Main + 0x146d
ffffffff ffffffff bffde000 DLMMfgContextSolver! __TmainCRTStartup + 0x10f
// Code snippet below
void main()
{
atexit(MyCallBack);
exit(0);
}
void MyCallBack()
{
// Waitingforsingleobject() // Waits until all threads are terminated
}
EXE вызывает DllMain с флагом DLL_THREAD_DETACH, и мы имеем явную обработку, как показано ниже
BOOL APIENTRY DllMain( HANDLE, DWORD dwReason, LPVOID )
{
if(dwReason == DLL_THREAD_DETACH)
{
F1();
F2();
}
}
F1()
{
const static CComBSTR bstrMethod = __ FUNCTION __ ;
}
F2()
{
const static CComBSTR bstrMethod = __ FUNCTION __ ;
}
Потоково ли безопасно иметь локальную статическую инициализацию внутри функции. Также я заметил, что если статическая переменная однажды инициализируется перед выходом () основного приложения, я не вижу никаких проблем. Кто-нибудь может объяснить, в чем может быть проблема?
Примечание: Но когда я делаю статическую переменную не статической, тупик не возникает, и проблема решается.
Также дайте мне знать любое альтернативное решение, которое может помочь в этой ситуации.
С нетерпением жду ответа.