从解构类中保护回调函数的最佳方法

时间:2013-11-20 17:10:29

标签: c++ multithreading

确保回调对象的线程安全有什么好处/最佳?具体来说,我试图阻止回调对象在所有线程完成之前被解构。

很容易编写客户端代码以确保线程安全,但我正在寻找一种更简化的方法。例如,使用工厂对象生成回调对象。问题在于跟踪回调对象的使用情况。

以下是我正在努力改进的示例代码。

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 个答案:

答案 0 :(得分: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.