2013-02-18 103 views
1

在将项目迁移到带有msvc110的C++ 11标准的过程中,不幸的是,在dll上使用的线程变量与我的boost版本有所不同。C++ 11线程vs升级线程

所以,最初这是在msvc90上工作,基本上Dll调用一个线程创建的InitDll。 该线程基本上作为一个监听程序以及dll的主线程。 现在,当我创建线程时,它挂起并不执行任何操作,甚至不执行用于初始化线程的函数。

你能帮我解释我怎么能得到与升压版相同的行为?

编辑:CODE

很抱歉,无法回复的评论

应用程序使用记录器通过一个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(); 
} 
+2

你应该发布一些代码。但是,这听起来像你可能在'DllMain()'中执行这个init。在DllMain()中执行重要的工作是一项非常危险的工作。请参阅文档的注释部分:http://msdn.microsoft.com/en-us/library/ms682583.aspx和http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/ 63401.aspx或http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx – 2013-02-18 18:26:20

+0

谢谢Micheal,非常真实。我读过关于在DllMain上做些花哨的东西,不管我在这里是否真的发明过轮子。我只是将代码作为日志库的示例dll_and_exe的参考http://torjo.com/log2/doc/html/index.html – notNullGothik 2013-02-18 22:29:32

+0

自从我在前面实现它之后,没有改变任何特定行为,它迄今为止工作很好。你会推荐我初始化图书馆的正确方法吗?我记得有点挣扎,试图从DLLMain中删除init并将它调用到其他地方,如果我记得确切的问题,会发布更多。 – notNullGothik 2013-02-18 22:32:03

回答

2

您的InitLog函数有一个线程,该线程显示为该函数的作用域。当函数退出时,它立即执行,线程被销毁。但是,破坏一个未加入的std :: thread(但不是boost :: thread?)会调用std :: terminate。如果你想测试那是发生了什么,请加入终止处理程序。

+0

我相信最近版本的Boost.Thread [对齐](http://stackoverflow.com/q/11393936/283302)一个unjoined'std :: thread'的行为 – 2013-02-19 02:40:07

+0

没错,旧版本不太确定,考虑到OP提到VS 9.0(aka 2005),Boost也可能是旧版本。 – metal 2013-02-19 02:47:22

+0

我照顾有最新的库与迁移过程,boost_1_53_0 – notNullGothik 2013-02-19 02:54:43

3

如果DllMain出问题了,那么你在做什么时会受到严重的限制---通常Windows加载器会终止应用程序,并且通常不会调用错误处理程序。

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

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

+0

谢谢,似乎是这样。我会坚持一个来自main的初始化调用,就像我之前在上面的评论中指出的那样。不想将此泄露给用户,但我目前看不到解决方法。 – notNullGothik 2013-02-19 15:15:44

+0

您可以使用'std :: call_once',如我的编辑中所述。 – 2013-02-19 15:24:26