【发布时间】:2016-10-21 18:15:43
【问题描述】:
我的简化问题
我读了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++;
}
【问题讨论】:
-
m_IO.~io_service();-- 如果我曾经见过,那就是代码味道,尤其是在这种情况下。您提到的问题特别提到用户无法控制相关代码,因此他们不得不诉诸这种恶作剧(无论如何您都没有正确实现,因为您没有重新创建对象)。如果您需要更好地控制其生命周期,该问题还包含一条带有明智建议动态分配io_service的评论。但是,这与此处无关,因为问题出在其余代码上,而不是删除io_service。 -
谢谢你的回复,如果我想在
deadline_timer的帮助下实现一个每日定时器,我该怎么办? -
我正在研究一个答案,但请给我一些时间来整理。
-
不要直接使用
asio::io_service,而是使用boost::optional<asio::io_service>,在构造函数中初始化它,然后调用m_IO.~io_service而不是调用m_IO.reset()。我在任何地方都没有看到你的 EndThread 函数,所以我只是要注意,你必须确保线程是joined并且在销毁 @ 之前销毁每个 asio IO 对象(例如 m_pTimer) 987654349@.