在Windows DLL中使用boost :: asio :: deadline_timer时出现死锁

时间:2017-08-11 15:15:08

标签: c++ dll boost-asio

我正在尝试在DLL中使用Boost-Deadlinetimer,它使用boost :: dll :: shared_library加载。以下代码片段简化为必需品。

example.h文件:

#include <boost/asio.hpp>
class Example  
{  
public:  
    Class() : m_timer(m_ioService) { } 
    virtual ~Class() { }  
    //...    
private:  
    boost::asio::io_service m_ioService;  
    boost::asio::deadline_timer m_timer;
    //...
};

Example.cpp:

#include "Example.h"
#include <boost/config.hpp>
//...
extern "C" BOOST_SYMBOL_EXPORT Example MyExample;
Example MyExample;

Main.cpp的:

#include <boost/dll/Import.hpp>
//...
boost::dll::shared_library lib("Example.dll", boost::dll::load_mode::Default_mode);
//...

我的问题是,只要m_timer在构造函数的初始化列表中,加载已编译的dll时就会出现死锁。

m_timer替换为boost::shared_ptr并在构造函数(或后续函数)中初始化时, loading no 死锁> dll,但卸载 dll时出现死锁。

无论如何,我无法在Windows dll中真正使用全局截止时间计时器对象。

1 个答案:

答案 0 :(得分:3)

Windows有一个LoaderLock,它会在调用LoadLibrary之前保留,直到它返回。

Windows系统使用此锁定以确保进程保持稳定,因为级联DLL已正确引用计数。

在DLL中创建的全局变量在DllMain运行(dynamic initialization)之前由DLL_PROCESS_ATTACH构造,并在DllMain完成(DLL_PROCESS_DETACH)之后销毁。

使用全局变量创建DLL时,需要遵循链接中的规则,并避免...

  • 加载DLL
  • 使用锁定 - 锁定转换的原因
  • 创建流程
  • 阅读注册表
  • 创建/销毁线程
  • 使用StringType函数。

处理这个问题的最简单方法是在LoadLibrary之后调用一个单独的初始化函数,并在最终FreeLibrary之前调用一个Uninitialize函数,其中全局变量被单独初始化。