2015-06-25 134 views
0

下面的源不会编译使用MSVC 12升压deadline_timer编译问题

IMCThreadMngr.cpp

#include "IMCThreadMngr.h" 


CIMCThreadMngr::CIMCThreadMngr() : mService(), 
mWork(mService) 
{} 

CIMCThreadMngr::~CIMCThreadMngr() {}; 


void CIMCThreadMngr::StopManager() 
{ 
    std::cout << "Manager ceasing" << std::endl; 
    mService.stop(); 
    mServicethread.join(); 
    std::cout << "Manager ceased" << std::endl; 
} 

void CIMCThreadMngr::StartManager() 
{ 
    mServicethread = boost::thread(boost::bind(&boost::asio::io_service::run, &mService)); 
} 

void CIMCThreadMngr::RegisterThread(const std::string& name, int timeout) 
{ 
    if (name.length() == 0) { 
     std::cout << "No thread name provided" << std::endl; 
     return; 
    } 
    boost::mutex::scoped_lock lock(mGroupMutex); 

    ThreadObject ob = ThreadObject(mService); 
    ob.name_ = name; 
    if (timeout > 0) { 
    ob.timeout_ = timeout; 
    } 
    else { 
    ob.timeout_ = 2000; 
    } 
    mThreadGroup.push_back(ob); 

} 

void CIMCThreadMngr::UnRegisterThread(const std::string& name) 
{ 
    if (name.length() == 0) { 
     std::cout << "No thread name provided" << std::endl; 
     return; 
    } 

    boost::mutex::scoped_lock lock(mGroupMutex); 

    std::vector<ThreadObject>::iterator obref; 
    if (FindThreadObject(name, obref)){ 
     mThreadGroup.erase(obref); 
    } 
} 

void CIMCThreadMngr::ThreadCheckIn(const std::string& name){ 

    if (name.length() == 0) { 
     std::cout << "No thread name provided" << std::endl; 
     return; 
    } 

    boost::mutex::scoped_lock lock(mGroupMutex); 

    std::vector<ThreadObject>::iterator obref; 
    if (FindThreadObject(name, obref)){ 
     obref->timer_.cancel(); 
     obref->timer_.expires_from_now(boost::posix_time::seconds(obref->timeout_)); 
     obref->timer_.async_wait(boost::bind(&CIMCThreadMngr::TimeoutElapsed, this)); 
    } 
} 

bool CIMCThreadMngr::FindThreadObject(const std::string name, std::vector<ThreadObject>::iterator& ob){ 

    for (ob = mThreadGroup.begin(); ob != mThreadGroup.end(); ob++) { 
     if ((ob->name_.compare(name) == 0)) { 
      return true; 
     } 
    } 
    return false; 
} 

void CIMCThreadMngr::TimeoutElapsed(const boost::system::error_code& e, const std::string& name){ 

    boost::mutex::scoped_lock lock(mGroupMutex); 

    if (e != boost::asio::error::operation_aborted) 
    { 
     std::cout << "Thread " << name << " did has not responded" << std::endl; // Timer was not cancelled, take necessary action. 
     ThreadCheckIn(name); 
    } 
} 

IMCThreadMngr.h

#include <boost/asio.hpp> 
#include <boost/bind.hpp> 
#include <boost/thread.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread/mutex.hpp> 
#include <vector> 


class CIMCThreadMngr { 

public: 

    struct ThreadObject { 

     std::string name_; 
     int timeout_; 
     bool threadrunning_; 
     boost::posix_time::ptime lastupdate_; 
     boost::asio::deadline_timer timer_; 

     ThreadObject(boost::asio::io_service& service) : timer_(service) 
     { 
      timer_.expires_from_now(boost::posix_time::millisec(3000)); 
     } 

    }; 

public: 
    CIMCThreadMngr(); 
    ~CIMCThreadMngr(); 

    void StopManager(); 
    void StartManager(); 

    void RegisterThread(const std::string& name, int timeout); 
    void UnRegisterThread(const std::string& name); 
    void ThreadCheckIn(const std::string& name); 
    bool FindThreadObject(const std::string name, std::vector<ThreadObject>::iterator& ob); 
    void TimeoutElapsed(const boost::system::error_code& e, const std::string& name); 
    void TimeoutElapsed(); 

private: 

    boost::asio::io_service mService; 
    boost::asio::io_service::work mWork; 
    boost::thread mServicethread; 
    std::vector<ThreadObject> mThreadGroup; 
    boost::mutex mGroupMutex; 

}; 

我遇到编译器的问题是如下

f:\boost\boost_1_57_0\boost\asio\basic_deadline_timer.hpp(510): error C2248: 'boost::asio::basic_io_object<TimerService,false>::operator =' : cannot access private member declared in class 'boost::asio::basic_io_object<TimerService,false>' 
      with 
      [ 
       TimerService=boost::asio::deadline_timer_service<boost::posix_time::ptime,boost::asio::time_traits<boost::posix_time::ptime>> 
      ] 
      f:\boost\boost_1_57_0\boost\asio\basic_io_object.hpp(164) : see declaration of 'boost::asio::basic_io_object<TimerService,false>::operator =' 
      with 
      [ 
       TimerService=boost::asio::deadline_timer_service<boost::posix_time::ptime,boost::asio::time_traits<boost::posix_time::ptime>> 
      ] 
      This diagnostic occurred in the compiler generated function 'boost::asio::basic_deadline_timer<boost::posix_time::ptime,boost::asio::time_traits<boost::posix_time::ptime>,boost::asio::deadline_timer_service<Time,TimeTraits>> &boost::asio::basic_deadline_timer<Time,TimeTraits,boost::asio::deadline_timer_service<Time,TimeTraits>>::operator =(const boost::asio::basic_deadline_timer<Time,TimeTraits,boost::asio::deadline_timer_service<Time,TimeTraits>> &)' 
      with 
     [ 
      Time=boost::posix_time::ptime,   TimeTraits=boost::asio::time_traits<boost::posix_time::ptime> 
     ] 

希望这个问题是相当直接的,尽管我无法在上面的代码和deadline_timer的boost示例之间找到明显的区别。

回答

0

boost::asio::deadline_timer既不可复制也不可移动(既不可复制也不可移动)。因此,既不是CIMCThreadMgr::ThreadObject,这意味着您不能有std::vector<ThreadObject>

解决此问题的一个简单的方法就是保持deadline_timershared_ptr,如

struct ThreadObject { 
    std::string name_; 
    int timeout_; 
    bool threadrunning_; 
    boost::posix_time::ptime lastupdate_; 

    // HERE 
    std::shared_ptr<boost::asio::deadline_timer> timer_; 

    ThreadObject(boost::asio::io_service& service) 
     // Also HERE 
     : timer_(std::make_shared<boost::asio::deadline_timer>(service)) 
    { 
     // -> instead of . now. 
     timer_->expires_from_now(boost::posix_time::millisec(3000)); 
    } 
}; 

如果你走这条路,你也有被使用,其中timer_->更换.

if (FindThreadObject(name, obref)){ 
    //   vv-- HERE 
    obref->timer_->cancel(); 
    obref->timer_->expires_from_now(boost::posix_time::seconds(obref->timeout_)); 
    obref->timer_->async_wait(boost::bind(&CIMCThreadMngr::TimeoutElapsed, this)); 
} 

这可能是可以使用std::unique_ptr,但可能需要对你的代码较大的变化比->更换.在一些地方(因为ThreadObject只能移动但不可复制)。

+0

嗯,这是一个愚蠢的监督!感谢您及时的回复! – tuskcode