我正在处理一些通讯代码,因此需要一个定期的计时器进行监视。我在通讯中使用boost ASIO,所以我决定使用截止时间计时器进行计时,并将其放在相同的IO服务上。
第一次运行代码,一切都很好,但是一旦通信(在我的情况下是串行端口)停止并重新启动,它就会出错。计时器开始出现故障,通讯中断。我相信这两者是相关的,所以我只关注这个问题的计时器。
请考虑以下代码。这应该启动一个计时器并使其运行10秒钟,然后停止计时器,然后再重新启动10秒钟。但是实际上发生的是,当计时器重新启动时,它将连续触发,即两次触发之间没有任何延迟。
#include <iostream>
#include <thread>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
boost::posix_time::ptime timer_start_;
void CallbackTimerFunc(boost::asio::deadline_timer* timer) {
auto time_since_start = timer->expires_at() - timer_start_;
std::cout << "It's been " << time_since_start.total_seconds() << " seconds." << std::endl;
// Sleep is here to prevent spamming when timer starts malfunctioning.
usleep(20000);
timer->expires_at(timer->expires_at() + boost::posix_time::milliseconds(1000));
timer->async_wait(boost::bind(&CallbackTimerFunc,timer));
}
int main(int /*argc*/,char** /*args*/) {
// Start
boost::asio::io_service io_service_;
boost::asio::deadline_timer deadline_timer_(io_service_);
deadline_timer_.expires_from_now(boost::posix_time::milliseconds(1000));
timer_start_ = deadline_timer_.expires_at();
deadline_timer_.async_wait(boost::bind(&CallbackTimerFunc,&deadline_timer_));
std::thread io_thread_(boost::bind(&boost::asio::io_service::run,&io_service_));
// Stop
sleep(10);
io_service_.stop();
while (!io_service_.stopped()) usleep(10000);
deadline_timer_.cancel();
io_thread_.join();
std::cout << "******************************" << std::endl;
// Restart
io_service_.restart();
deadline_timer_.expires_from_now(boost::posix_time::milliseconds(1000));
timer_start_ = deadline_timer_.expires_at();
deadline_timer_.async_wait(boost::bind(&CallbackTimerFunc,&deadline_timer_));
io_thread_ = std::thread(boost::bind(&boost::asio::io_service::run,&io_service_));
// Stop
sleep(10);
io_service_.stop();
while (!io_service_.stopped()) usleep(10000);
deadline_timer_.cancel();
io_thread_.join();
return 0;
}
该计时器的预期输出计数两次为10(实际上是从0到8)。实际的输出是它计数到10次,然后haywire声称经过了数百秒。
我可以通过创建全新的IO服务和计时器来使此代码正常工作,但是鉴于它们应该可重用,这似乎是不必要的。
如果有人可以告诉我这里发生了什么,或者至少重现了我的结果,我将不胜感激。