2014-03-26 61 views
1

在我的多線程程序中,我經常使用如下所示的方法來同步訪問數據:等待異步方法來完成

class MyAsyncClass 
{ 

public:  // public thread safe interface of MyAsyncClass 

    void start() 
    { 
     // add work to io_service 
     _ioServiceWork.reset(new boost::asio::io_service::work(_ioService)); 

     // start io service 
     _ioServiceThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &_ioService))); 
    } 

    void stop() 
    { 
     _ioService.post(boost::bind(&MyAsyncClass::stop_internal, this)); 

     // QUESTION: 
     // how do I wait for stop_internal to finish here? 

     // remove work 
     _ioServiceWork.reset(); 

     // wait for the io_service to return from run() 
     if (_ioServiceThread && _ioServiceThread->joinable()) 
      _ioServiceThread->join(); 

     // allow subsequent calls to run() 
     _ioService.reset(); 

     // delete thread 
     _ioServiceThread.reset(); 
    } 

    void doSometing() 
    { 
     _ioService.post(boost::bind(&MyAsyncClass::doSometing_internal, this)); 
    } 

private:  // internal handlers 

    void stop_internal() 
    { 
     _myMember = 0; 
    } 

    void doSomething_internal() 
    { 
     _myMember++; 
    } 

private:  // private variables 

    // io service and its thread 
    boost::asio::io_service _ioService; 
    boost::shared_ptr<boost::thread> _ioServiceThread; 

    // work object to prevent io service from running out of work 
    std::unique_ptr<boost::asio::io_service::work> _ioServiceWork; 

    // some member that should be modified only from _ioServiceThread 
    int _myMember; 

}; 

這個類的公共接口是線程安全的意義它的公共方法可以從任何線程調用,並且boost::asio::io_service注意同步對此類的私有成員的訪問。因此,公衆doSomething()除了將實際工作發佈到io_service之外不做任何事情。

start()stop()方法MyAsyncClass明顯在MyAsyncClass開始和停止處理。我希望能夠從任何線程調用MyAsyncClass::stop(),並且在MyAsyncClass的未初始化完成之前它不應該返回。

因爲在這種特殊情況下,我需要在停止時修改其中一個私人成員(需要同步訪問),我引入了一個stop_internal()方法,我從stop()發佈到io_service

現在的問題是:我如何等待執行stop_internal()完成stop()?請注意,我不能直接調用stop_internal(),因爲它會在錯誤的線程中運行。

編輯:

這將是很好有一個解決方案,同時工作,如果MyAsyncClass::stop()_ioServiceThread叫,讓MyAsyncClass也可自行停止。

回答

1

我只是找到了一個非常好的解決自己:

除刪除工作在stop()(重置_ioServiceWork),我做這件事的stop_internal()結束。這意味着_ioServiceThread->join()阻止,直到stop_internal()完成 - 正是我想要的。

這個解決方案的好處是它不需要任何互斥或條件變量或類似的東西。