我正在使用msvc110将项目迁移到c ++ 11标准,不幸的是,在dll上使用的线程变量的行为与我的boost版本不同。
所以,最初这是在msvc90上工作,基本上Dll调用创建线程的InitDll。 该线程基本上与dll的主线程一起充当监听器。 现在,当我创建线程时,它会挂起并且什么也不做,甚至不执行用于初始化线程的函数。
你能帮我解释一下我怎么能得到与升级版相同的行为?
编辑:代码
抱歉,无法回复评论中的代码
应用程序通过dll使用记录器。 在非常简单的控制台应用程序中使用记录器就像这样
#include <Somewhere/Logger.h>
int main()
{
COOL_LOGGER("Here we go logging on console!");
return 0;
}
我们可以讨论编写代码的方式(取自我提到的演示),但是如何初始化dll和线程是:
#include "Logger.h"
#ifdef _WIN32
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
TheLog::InitLog();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
#include <thread>
void InitLog()
{
// Do the init taken from library demos
std::thread m_thread(LogListener);
}
void LogListener()
{
while(!bAppEnd)
{
std::cin>>str;
// change log behavior according to the user input
}
}
// to stop the thread when shutting down
void EndLog()
{
// retrieve thread thought id or some other way
thread.join();
}
答案 0 :(得分:3)
如果在DllMain
中出现问题,那么你所做的事情就会受到严重限制 - 通常Windows加载器只会终止应用程序,而且通常不会调用错误处理程序。
挂起表明代码正在执行需要加载DLL的操作,或者正在等待另一个DLL初始化,在此DLL的DllMain
调用完成之前,这两种情况都不会发生。 std::thread
的实施可能正在做其中一件事。
编辑:避免此问题的一种方法是在与此后台线程通信的每个导出函数中使用std::call_once
,以确保线程已启动。这样你就不会在std::thread
中使用DllMain
,但是你不需要公开“init”函数。
答案 1 :(得分:2)
您的InitLog函数有一个显示为该函数范围的线程。当函数退出时,它立即执行,线程被销毁。但是,破坏未加入的std :: thread(但不是boost :: thread?)会调用std :: terminate。如果你想测试那就是发生了什么,请加入终止处理程序。