2017-08-11 103 views
3

我想在使用boost :: dll :: shared_library加载的DLL中使用Boost-Deadlinetimer。以下代码片段被简化为基本要素。在Windows DLL中使用boost :: asio :: deadline_timer时出现死锁

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); 
//... 

我的问题是,有一个僵局,而加载的dll编译只要m_timer在构造函数的初始化列表中。

当由boost::shared_ptr替换m_timer和初始化,在构造(或随后的功能),那么就没有死锁装载的dll但死锁而卸载该DLL。

无论如何,我不能真正使用Windows DLL中的全局截止时间定时器对象。

回答

2

Windows有一个LoaderLock,它从LoadLibrary的呼叫持有,直到它返回。

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

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

当你创建一个全局变量DLL,您需要按照该链接的规则,避免...

  • 加载DLL
  • 使用锁 - 锁反转的原因
  • 创建进程
  • 读取注册表
  • 使用StringType功能创建/销毁线程

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

相关问题