boost deadline_timer 编译问题
boost deadline_timer compile issue
以下源代码无法使用 MSVC 12 进行编译。
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::asio::deadline_timer
既不可复制也不可移动(既不可复制也不可移动)。结果,CIMCThreadMgr::ThreadObject
也不是,这意味着您不能有 std::vector<ThreadObject>
.
解决此问题的一个简单方法是将 deadline_timer
保持在 shared_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
只能移动但不能复制)。
以下源代码无法使用 MSVC 12 进行编译。
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::asio::deadline_timer
既不可复制也不可移动(既不可复制也不可移动)。结果,CIMCThreadMgr::ThreadObject
也不是,这意味着您不能有 std::vector<ThreadObject>
.
解决此问题的一个简单方法是将 deadline_timer
保持在 shared_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
只能移动但不能复制)。