1

我正在使用 msvc110 将我的项目迁移到 c++11 标准,不幸的是,在 dll 上使用的线程变量的行为与我所拥有的 boost 版本不同。

所以,最初这是在 msvc90 上工作的,基本上 Dll 调用了一个创建线程的 InitDll。该线程基本上与 dll 的主线程一起充当侦听器。现在,当我创建线程时,它挂起并且什么也不做,甚至不执行用于初始化线程的函数。

您能帮我解释一下如何获得与 boost 版本相同的行为吗?

编辑:代码

抱歉,无法回复评论中的代码

应用程序通过 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();
 }
4

2 回答 2

3

如果出现问题,DllMain那么您的操作将受到严重限制——Windows 加载程序通常只会终止应用程序,并且通常不会调用错误处理程序。

挂起表明代码正在执行需要加载 DLL 的操作,或者正在等待另一个 DLL 初始化,这两种情况都不会发生,直到DllMain对该 DLL 的调用完成。有可能std::thread是在做这些事情之一。

编辑:避免该问题的一种方法是std::call_once在与此后台线程通信的每个导出函数中使用,以确保启动线程。这样您就不会使用std::threadin DllMain,但您不需要公开“init”函数。

于 2013-02-19T09:47:37.780 回答
2

您的 InitLog 函数有一个线程,该线程的范围似乎仅限于该函数。当函数退出时,它立即执行,线程被销毁。然而,销毁未连接的 std::thread(但不是 boost::thread?)调用 std::terminate。如果您想测试正在发生的事情,请放入终止处理程序。

于 2013-02-19T02:26:56.557 回答