我的简化问题
我读了this thread,我试图删除io_service对象。我这样做
m_IO.stop();
m_IO.~io_service();
m_IO是boost::asio::io_service
的对象。我发现我的帖子被m_IO.~io_service();
屏蔽了。如何删除io_service
?
我的完整问题
我通过使用boost io_service和截止时间计时器来制作每日计时器。问题是当我想删除我的日常计时器时,我的线程会在尝试删除boost io_service时消失。
main.cpp
int main()
{
myDailyTimer* pTimer = new myDailyTimer;
// do something
delete pTimer;
return 0;
}
我在myDailyTimer.cpp::int i = 0;
和myDailyTimer.cpp::int j = 0;
和main::return 0;
设置了分数点我的主线程可以达到int i = 0;
,我的计时器线程无法到达int j = 0;
,我的主线程无法到达return 0;
。
我发现我的主线程在尝试删除boost::asio::io_service
对象时会消失。如何解决这个问题呢?我是以错误的方式使用boost::asio::io_service
吗?
myDailyTimer.h
class myDailyTimerInterface
{
public:
myDailyTimerInterface(){}
~myDailyTimerInterface(){}
virtual void TimerCallback(int nTimerID) = 0;
};
class myDailyTimer :
public myThread
{
public:
boost::asio::io_service m_IO;
boost::asio::deadline_timer * m_pTimer;
tm m_tmSpecificTime;
std::string m_strSpecificTime;
int m_nTimerID;
myDailyTimerInterface* m_pParent;
public:
myDailyTimer();
~myDailyTimer();
void SetTime(tm strIN, int nID); // msec
void TimerCallback();
//Override
void ThreadMain();
protected:
std::string MakeStringSpecificTime();
void AddOneDay();
};
myDailyTimer.cpp
myDailyTimer::myDailyTimer()
{
m_pTimer = 0;
m_strSpecificTime = "";
}
myDailyTimer::~myDailyTimer()
{
EndThread();
if (m_pTimer != 0)
{
m_pTimer->cancel();
delete m_pTimer;
}
m_IO.stop();
m_IO.~io_service();
int i = 0;
i++;
}
void myDailyTimer::SetTime(tm tmIN, int nID) // msec
{
if (m_pTimer != 0)
{
m_pTimer->cancel();
delete m_pTimer;
}
m_tmSpecificTime = tmIN;
m_strSpecificTime = MakeStringSpecificTime();
m_nTimerID = nID;
m_pTimer = new boost::asio::deadline_timer(m_IO, boost::posix_time::time_from_string(m_strSpecificTime));
m_pTimer->async_wait(boost::bind(&myDailyTimer::TimerCallback, this));
myThread::Start();
}
std::string myDailyTimer::MakeStringSpecificTime()
{
time_t localTime;
localTime = mktime(&m_tmSpecificTime); // time is GMT local
struct tm * ptm = gmtime(&localTime); // convert time to GMT +0
char veccNextTime[64];
memset(veccNextTime, 0, sizeof(veccNextTime));
sprintf(veccNextTime, "%d-%02d-%02d %02d:%02d:%02d.000",
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
std::string strTemp(veccNextTime);
return strTemp;
}
void myDailyTimer::AddOneDay()
{
m_tmSpecificTime.tm_mday += 1;
mktime(&m_tmSpecificTime); /* normalize result */
}
void myDailyTimer::TimerCallback()
{
if (m_pParent != 0)
m_pParent->TimerCallback(m_nTimerID);
//m_timer->expires_from_now(boost::posix_time::milliseconds(m_nTimerDuration));
AddOneDay();
m_strSpecificTime = MakeStringSpecificTime();
m_pTimer->expires_at(boost::posix_time::time_from_string(m_strSpecificTime));
m_pTimer->async_wait(boost::bind(&myDailyTimer::TimerCallback, this));
}
//Override
void myDailyTimer::ThreadMain()
{
while (!IsEndThread())
m_IO.run();
int j = 0;
j++;
}
答案 0 :(得分:1)
正如DanMašek所提到的,明确地调用析构函数并不是一个好的模式。停止io_service
的标准方法是停止待处理的每个“工作”,然后等待io_service::run
函数返回。另外,为了防止io_service::run
函数过早返回,最好创建一个io_service::work
对象的实例。
希望您能够将此示例修改为您的用例:
namespace asio = boost::asio;
class MyTimer {
using Clock = std::chrono::steady_clock;
public:
MyTimer(Clock::duration duration)
: _work(_ios)
, _timer(_ios)
, _thread([this] { _ios.run(); })
{
_ios.post([this, duration] { start(duration); });
}
~MyTimer() {
_ios.post([this] { stop(); });
_thread.join();
}
private:
void start(Clock::duration duration) {
_timer.expires_from_now(duration);
_timer.async_wait([this](boost::system::error_code) {
// NOTE: Be careful here as this is run from inside
// the thread.
if (!_work) {
// Already stopped.
std::cout << "Stopped" << std::endl;
return;
}
std::cout << "Timer fired" << std::endl;
});
}
void stop() {
_work.reset();
_timer.cancel();
}
private:
asio::io_service _ios;
boost::optional<asio::io_service::work> _work;
asio::steady_timer _timer;
std::thread _thread;
};
int main() {
auto* my_timer = new MyTimer(std::chrono::seconds(1));
delete my_timer;
return 0;
}