I have a task to do something every "round" minute(at xx:xx:00) And I use something like
const int statisticsInterval=60;
time_t t=0;
while (1)
{
if (abs(t-time(NULL)==0)) //to avoid multiple calls in the same second that is the multiple of 60
boost::this_thread::sleep(boost::posix_time::seconds(2));//2, not 1 to make sure that 1 second passes
t=time(NULL);
boost::this_thread::sleep(boost::posix_time::seconds(statisticsInterval-(t%statisticsInterval)));
//DO WORK
}
As you can see I use sleep (60sec - number of elapsed seconds in current minute). But one programmer told me that it is not precise and that i should change it to while loop with sleep(1) inside. I consider it highly doubtful that he is right, but I just wanted to check is somebody knows if there is less of a precision if the sleep interval is long. I presume that sleep is implemented in a way that at certain time in the future trigger is activated and thread is put into "ready to execute thread group" so I see no reason for diff in precision. BTW OS is ubuntu and I dont care about less than 2-3 sec errors. For example if I sleep for 52 secs, 53.8 sleep is totally acceptable. P.S. I know about sleep defining the minimal time, and that theoretically my thread might get activated in year 2047., but I'm asking about realistic scenarios.
When you do sleep(N) it tells the OS to trigger the thread at current time + N.
The reason why it isn't always accurate, is that you're not the only thread in the system.
There might be another thread that asked to be waken at that time before you, and there might just be some important OS stuff that's needed to be performed exactly at that time.
Anyway, there shouldn't be any precision issues, because the method has nothing to do with N.
The only reason that it won't be "precise" is if it's a crappy OS that can't calculate the time right. And then again, the loop won't solve that.
In some threading APIs, it's possible to be awoken before the sleep completes (eg, due to a signal arriving during the sleep). The correct way to handle this is to compute an absolute wake up time, then loop, sleeping for the remaining duration. I would imagine sleeping for one-second intervals to be a hack to approximate this, poorly.
However, the boost threading API's this_thread::sleep()
is not documented to have these early wakeups, and so this technique is not necessary (the boost thread API does the loop for you).
Generally speaking, there are very few cases where using smaller sleep intervals improves wakeup latency significantly; the OS handles all wakeups more or less the same way. At best, you might keep the cache warm and avoid pageouts, but this would only affect the small portion of memory directly involved in the sleep loop.
Furthermore, most OSes deal with time using integer counters internally; this means that large intervals do not induce rounding errors (as you might find with floating point values). However, if you are using floating point for your own computation, this may be an issue. If you are currently using floating point intervals (say, a double
of seconds since 1970), you may wish to consider integer units (say, a long long
of milliseconds since 1970).
sleep is not very precise in many cases. It depends on the OS how precise. In Windows 7, timer resolution is about 15,4 ms I think. Also, you can usually tell the scheduler how to handle sleep slacking...
Here is a good read:
Linux: http://linux.die.net/man/3/nanosleep
Windows: http://msdn.microsoft.com/en-us/library/ms686298(v=vs.85).aspx
PS: if you want higher precision on long waits, sleep some period and use the time diff based on a real-time clock. I.e. Store the current time when you start sleeping, then at each interval check how far you are from the set wait time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With