2017-08-11 51 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函數,其中全局變量是單獨初始化的。

相關問題