If you want your timer to fire repeatedly, you can just call deadline_timer::expires_from_now
and deadline_timer::async_wait
in your timer callback. This will make the timer re-schedule itself each time it fires.
The timers are associated with an io_service
object, which should be run on one or more threads. You can have any number of timers associated with a single io_service
. If you want your timers to be executed serially and not worry about concurrency issues, just have a single thread run your io_service
.
In this example, I have one thread running one io_service with two timers.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/chrono.hpp>
boost::asio::io_service io;
boost::asio::deadline_timer timerA(io);
boost::asio::deadline_timer timerB(io);
boost::chrono::steady_clock::time_point appStart;
void onTimerA(const boost::system::error_code& error)
{
assert(!error);
std::cout << "A fired at " <<
boost::chrono::duration_cast<boost::chrono::milliseconds>
(boost::chrono::steady_clock::now() - appStart).count()
<< std::endl;
timerA.expires_from_now(boost::posix_time::seconds(1));
timerA.async_wait(onTimerA);
}
void onTimerB(const boost::system::error_code& error)
{
assert(!error);
std::cout << "B fired at " <<
boost::chrono::duration_cast<boost::chrono::milliseconds>
(boost::chrono::steady_clock::now() - appStart).count()
<< std::endl;
timerB.expires_from_now(boost::posix_time::seconds(2));
timerB.async_wait(onTimerB);
}
int main()
{
// Prevents io.run() from returning.
boost::asio::io_service::work work(io);
appStart = boost::chrono::steady_clock::now();
timerA.expires_from_now(boost::posix_time::seconds(1));
timerA.async_wait(onTimerA);
timerB.expires_from_now(boost::posix_time::seconds(2));
timerB.async_wait(onTimerB);
io.run();
}
However, the downside of having one thread is that if one of the timer callbacks takes a long time to execute, it will block other timers that should have fired until it completes. If you know that your timer callbacks won't take long, one thread will be fine, though.
For example, if you have timer A on 25 ms intervals and timer B on 50 ms intervals, the two timers will sometimes be scheduled to fire at the same time. One of them will execute first, the other will wait for that execution to complete, and then execute itself.
If you do expect your timer callbacks to take a long time and you can't have your timers waiting on other timers' callbacks to finish, you need additional threads running your io_service
.