это ошибка CRT.сбой, потому что деструктор std::condition_variable
вызван из DLL_PROCESS_DETACH
.
MyQueue queue
создан как глобальная переменная, а cond_
являются переменными-членами MyQueue
потому что cond_
является глобальным объектом в DLL - его деструктор вызывается по DLL_PROCESS_DETACH
из трассировки стека, ясно видно, что все начинаются с _Cnd_destroy
(вызывается из деструктора условной переменной).Крит внутренне позвонить CreateThreadpoolWait
.который звонит TpAllocWait
.в самом начале этого API существует следующая строка кода:
if (RtlGetCurrentPeb()->Ldr->ShutdownInProgress) TppRaiseInvalidParameter();
, потому что CreateThreadpoolWait
вызывается после ExitProcess
вызываемого (смотрите трассировку стека ntdll!RtlExitUserProcess
) (в DLL_PROCESS_DETACH
обработчик) - ShutdownInProgress
уже true
и, как результат, TppRaiseInvalidParameter
вызван - снова очистить видимый из вашей трассировки стека.
здесь - std :: condition_variable destructor аварийно завершает работу на VS2012 Еще один пример этой аварии.- если вы посмотрите на трассировку стека аварии - вы можете увидеть, что она абсолютно одинакова (выделите основные точки в стеке)
ntdll.dll!_NtRaiseException@12
ntdll.dll!_KiUserExceptionDispatcher@8
ntdll.dll!_TpAllocWait@16
kernel32.dll!_CreateThreadpoolWait@12
msvcp110d.dll!_Cnd_destroy(_Cnd_internal_imp_t * * cond) Line 35 C++
ConnectModelUtil.dll!std::condition_variable::~condition_variable() Line 41 C++
ConnectModelUtil.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 416 C
ConnectModelUtil.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 522 C
, поэтому единственное решение здесь - не использовать глобальный condition_variable
объект в dll -в противном случае вы получите сбой DLL_PROCESS_DETACH
также из std :: condition_variable :: ~ condition_variable
Программист должен убедиться, что ни один поток не пытаетсяподождать * этого после запуска деструктора
, но в вашем случае это не так.Ваши потоки прервались во время ожидания условной переменной cond_.wait(mlock);
.Таким образом, с точки зрения условной переменной - потоки все еще ожидают - данные (указатели на блоки, выделенные из этого стека) связаны с условной переменной.вам нужно или как-то ожидать всех потоков перед вызовом ExitProcess
- но вы не можете сделать это из DLL_PROCESS_DETACH
, который вызывается после этого - для этого exe должен вызывать некоторую функцию dll до.или не использовать ожидание глобальной условной переменной dll