【发布时间】:2015-11-21 23:58:57
【问题描述】:
所以,这就是我要说的:std 很复杂。
在 VS2013 中这个简单的程序会导致死锁。
#include <thread>
#include <windows.h>
void foo()
{
}
void initialize()
{
std::thread t(foo);
}
BOOL APIENTRY DllMain(HMODULE, DWORD reason, LPVOID)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
initialize();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
在 DLLMain 中创建线程是完全错误的吗?这不是真的。从 Microsoft 的文档“创建 DLL 的最佳实践”: "如果您不与其他线程同步,创建线程可以工作 线程”。所以 CreateThread 有效,_beginthreadex 有效,并且 boost::thread 有效,但 std::thread 无效。这是 调用栈:
ntdll.dll!_NtWaitForSingleObject@12()
KernelBase.dll!_WaitForSingleObjectEx@12()
msvcr120d.dll!Concurrency::details::ExternalContextBase::Block() Line 151
msvcr120d.dll!Concurrency::Context::Block() Line 63
msvcr120d.dll!Concurrency::details::_Condition_variable::wait(Concurrency::critical_section & _Lck) Line 595
msvcp120d.dll!do_wait(_Cnd_internal_imp_t * * cond, _Mtx_internal_imp_t * * mtx, const xtime * target) Line 54
msvcp120d.dll!_Cnd_wait(_Cnd_internal_imp_t * * cond, _Mtx_internal_imp_t * * mtx) Line 81
msvcp120d.dll!std::_Cnd_waitX(_Cnd_internal_imp_t * * _Cnd, _Mtx_internal_imp_t * * _Mtx) Line 93
msvcp120d.dll!std::_Pad::_Launch(_Thrd_imp_t * _Thr) Line 73
mod.dll!std::_Launch<std::_Bind<1,void,void (__cdecl*const)(void)> >(_Thrd_imp_t * _Thr, std::_Bind<1,void,void (__cdecl*const)(void)> && _Tg) Line 206
mod.dll!std::thread::thread<void (__cdecl&)(void)>(void (void) * _Fx) Line 49
mod.dll!initialize() Line 17
mod.dll!DllMain(HINSTANCE__ * __formal, unsigned long reason, void * __formal) Line 33
好的,std::thread 将“与其他线程同步”。
但是为什么呢?
我希望这在 VS2015 中不再发生,我还没有测试过。
【问题讨论】:
-
std 并不复杂。似乎 MSFT 的线程实现有问题。
-
它试图与实际开始运行的线程保持良好并互锁。如果您有一个 1-800 的支持电话号码并且不特别喜欢来自未正确捕获其 lambda 参数的程序员的呼叫,您会倾向于做这种事情。使用调试器的 Debug > Windows > Threads 调试器窗口找出线程没有启动的原因。但是有些已成定局的结论是它也在尝试调用 DllMain() 入口点。加载程序锁死锁是一个标准错误。
标签: c++ visual-c++ msvc12