2013-11-20 47 views
0

確保回調對象的線程安全性最好/最好?具體來說,我試圖阻止一個回調對象在所有線程完成之前被解構。從解構類保護回調函數的最佳方法

爲了確保線程安全,很容易對客戶端代碼進行編碼,但我正在尋找一種更簡化的方式。例如,使用工廠對象來生成回調對象。麻煩在於跟蹤回調對象的使用情況。

下面是我試圖改進的示例代碼。

class CHandlerCallback 
{ 
public: 
    CHandlerCallback(){ ... }; 
    virtual ~CHandlerCallback(){ ... }; 
    virtual OnBegin(UINT nTotal){ ... }; 
    virtual OnStep (UINT nIncrmt){ ... }; 
    virtual OnEnd(UINT nErrCode){ ... }; 

protected: 
     ... 
} 

static DWORD WINAPI ThreadProc(LPVOID lpParameter) 
{ 
    CHandler* phandler = (CHandler*)lpParameter; 
    phandler ->ThreadProc(); 
    return 0; 
}; 

class CHandler 
{ 
public: 
    CHandler(CHandlerCallback * sink = NULL) { 
     m_pSink = sink; 
     // Start the server thread. (ThreadProc) 
    }; 
    ~CHandler(){...}; 

    VOID ThreadProc(LPVOID lpParameter) { 
     ... do stuff 
     if (m_pSink) m_pSink->OnBegin(..) 
     while (not exit) { 
      ... do stuff 
      if (m_pSink) m_pSink->OnStep(..) 
      ... do stuff 
     } 
     if (m_pSink) m_pSink->OnEnd(..); 
    }; 

private: 
    CHandlerCallback * m_pSink; 
} 

class CSpecial1Callback: public CHandlerCallback 
{ 
public: 
    CSpecial1Callback(){ ... }; 
    virtual ~CBaseHandler(){ ... }; 
    virtual OnStep (UINT nIncrmt){ ... }; 
} 

class CSpecial2Callback: public CHandlerCallback... 

然後運行的方式都類似於下面的代碼:

int main { 
    CSpecial2Callback* pCallback = new CSpecial2Callback(); 
    CHandler handler(pCallback); 
    // Right now the client waits for CHandler to finish before deleting 
    // pCallback 
} 

謝謝!

回答

1

如果您使用的是C++ 11,則可以使用智能指針來保持對象,直到對象的最後一個引用消失。見shared_pointer。如果你不在C++ 11中,你可以使用boost's version。如果你不想包含那個庫並且不在C++ 11中,你可以求助於使用該對象保持線程的內部計數,並在計數達到0時銷燬該對象。注意,試圖自己跟蹤該計數器可能會很困難,因爲您需要對計數器進行原子更新。

shared_ptr<CSpecial2Callback> pCallback(new CSpecial2Callback()); 
CHandler handler(pCallback); // You'll need to change this to take a shared_ptr 
... //Rest of code -- when the last reference to 
... //pCallback is used up it will be destroyed. 
+0

我也推薦線程安全引用計數智能指針。沒有C++ 11,就有可以提供這種功能的庫,例如Qt有一個合適的'QSharedPointer <>'類,但我想這不是一個選項。 –

+0

我使用C++ 11和shared_ptr可用於我,我完全忘了它。雖然,我希望有一個不依賴於ref計數的解決方案。但shared_ptr將很好地完成這項工作。謝謝! – rbhkamal