Я работаю над кодом связи, для которого мне нужен обычный таймер для мониторинга. Я использую повышение ASIO для связи, поэтому я решил использовать таймер крайнего срока для синхронизации и установить его на тот же сервис ввода-вывода.
Все работает отлично при первом запуске кода, но однажды он работает неправильносвязь (в моем случае последовательный порт) останавливается и перезапускается. Таймер начинает работать со сбоями, и связь обрывается. Я полагаю, что они связаны между собой, поэтому я просто сосредоточился на таймере для этого вопроса.
Рассмотрим код ниже. Это должно запустить таймер и дать ему поработать в течение 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 раз, а затем просто теряет сознание, утверждая, что проходят сотни секунд.
Я могу заставить этот код работать, создав совершенно новый сервис ввода-вывода и таймер, но это похоже надолжно быть ненужным, учитывая, что они должны быть многоразовыми.
Если кто-нибудь может сказать мне, что здесь происходит или хотя бы воспроизвести мои результаты, я был бы признателен.