简体   繁体   English

提高截止时间_计时器编译问题

[英]boost deadline_timer compile issue

The following source will not compile using MSVC 12. 以下源将无法使用MSVC 12进行编译。

IMCThreadMngr.cpp 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 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;

};

The compiler issue I am running into is as follows 我遇到的编译器问题如下

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>
         ]

Hopefully the issue is something fairly straight forward, though I can't find an obvious difference between my code above, and the boost examples of deadline_timer. 希望这个问题相当直截了当,尽管我在上面的代码和delighting_timer的boost示例之间找不到明显的区别。

boost::asio::deadline_timer is neither copyable nor moveable (nor copy-assignable nor move-assignable). boost::asio::deadline_timer既不可复制也不可移动(既不可复制也不可移动)。 As a result, neither is CIMCThreadMgr::ThreadObject , which means that you cannot have a std::vector<ThreadObject> . 结果, CIMCThreadMgr::ThreadObject都没有,这意味着您不能拥有std::vector<ThreadObject>

A simple way around this problem is to hold the deadline_timer in a shared_ptr , as in 解决此问题的一个简单的方法就是保持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));
    }
};

If you go this route, you'll also have to replace . 如果您走这条路线,则还必须替换. with -> where timer_ is being used: -> timer_使用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));
}

It is probably possible to use a std::unique_ptr , but that may require larger changes to your code than replacing . 可能可以使用std::unique_ptr ,但与替换相比,可能需要对代码进行更大的更改. with -> in a few places (because ThreadObject would only be moveable but not copyable). 在一些地方使用-> (因为ThreadObject只能移动,而不能复制)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM