deadline timer - wait every 5 seconds on the hour

Jul 5, 2012 at 9:09pm
I want to use Boost Deadline timer for a thread that will basically do work every 5 seconds. Simple enough, this is done. However, this thread will be spawned from a service that should be running 24/7, however, there will be times where the service may have to be restarted or taken offline for maintenance then restarted.

The problem: No matter what the current time is "now" I need the timer to do something every 5 seconds, from "on the hour".

What I mean is...
System starts up at 07:57:56 and the thread that will do work is started at this time. I don't want it to wait 5 seconds from now and every 5 seconds because that will result in 07:58:01, 07:58:06 doing work. I need it to be 07:58:00, 07:58:05, 07:58:10 etc. So basically I need the first wait time to be the difference between "now" and whatever time is needed to "sync" it up as I have proposed.

Here is a sample of how this is being used:

1
2
3
4
5
void scheduler(const boost::system::error_code& , boost::asio::deadline_timer * t)
{
   t->expires_at(t->expires_at() + boost::posix_time::seconds(5)); //This is ok once I'm in "sync" with the hour
   t->async_wait(boost::bind(print, boost::asio::placeholders::error, t));
}


I'm just wondering what the best approach for this is, because I'm not sure the granularity of the expires_at() is. Is there a way to get it precise? Is there a "best way" to set this up.

Thanks.
Last edited on Jul 5, 2012 at 9:10pm
Jul 5, 2012 at 9:36pm
expires_at() just returns whatever you gave it earlier. if you gave it current time rounded to the next 5 seconds the first time, that's what it will return, and adding another 5 seconds won't add 5.1 or 4.99.

Now if you start using expires_from_now(seconds(5)), you may encounter drift because current time is always a bit later than expires_at(): waking up takes time.
Last edited on Jul 5, 2012 at 9:43pm
Jul 5, 2012 at 9:51pm
Right. I guess I already knew the answer to my question. I just didn't know if anyone has done anything like this using boost before and already had a quick writeup on the subject.

So it looks like I will have to first:
1) Get the current time (UTC/GMT).
2) Find out the offset in seconds(microseconds/nanoseconds does it get this granular?) such that every 5 seconds would return a modulus of 0 using this offset + the current time... for the first wait time only.
3) Call expires_at the very first time using this offset.
4) proceed to use my example from above every 5 seconds (so there is no drift during processing).

It was #2 I guess I was referring to, I'd hate to do with and have the second be 99th of a second complete but since the granularity is only by the second, that be all that I can control. As well as, if someone has already done something like this. Otherwise I'll get around to it tomorrow.

edit example:
time 07:59:56:999
I would want the first time's wait to be 00:00:03:001 and not 00:00:04:000, because then I'd always be off by 999 milliseconds.

Thanks for the reply Cubbi.
Last edited on Jul 5, 2012 at 9:58pm
Jul 5, 2012 at 10:00pm
Yes, ptime is in nanoseconds where I used it, although it depends on the environment. It shouldn't matter since the ptime you're creating for the first call has zero fractional seconds.
Jul 5, 2012 at 10:00pm
WOW, I guess I'm having "fatal LCD staring from cube" syndrome. That's something I should have thought of and if a peer would have asked me what I was asking that is probably the same simple and accurate answer I would have given.

Hah thanks.
Topic archived. No new replies allowed.