views:

525

answers:

3

I recently came across the need to sleep the current thread for an exact period of time. I know of two methods of doing so on a POSIX platform: using nanosleep() or using Boost::this_thread::sleep().

Out of curiosity more than anything else, I was wondering what the differences are between the two approaches. Is there any difference in precision, and is there any reason not to use the Boost approach?

nanosleep() approach:

#include <time.h>
...
struct timespec sleepTime;
struct timespec returnTime;
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = 1000;
nanosleep(&sleepTime, &returnTime);

Boost approach:

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp> 
...
boost::this_thread::sleep(boost::posix_time::nanoseconds(1000));
A: 

is there any reason not to use the Boost approach

I suppose this is kind of obvious, but the only reason I can think of is that you'd require boost to compile your project.

Billy ONeal
I suppose I should have said the project already uses other boost libraries. Nonetheless, a valid answer to the general question.
Justin Ardini
+5  A: 

The few reasons why use boost that I can think of:

  • boost::this_thread::sleep() is an interruption point in boost.thread
  • boost::this_thread::sleep() can be drop-in replaced by C++0x's std::this_thread::sleep_until() in future

For why not -- if you're not using threads at all, or of everything else in your project uses POSIX calls, then nanosleep() makes more sense.

As for precision, on my system both boost and nanosleep() call the same system call, hrtimer_nanosleep(). I imagine boost authors try to get the highest precision possible on each system and for me it happens to be the same thing as what nanosleep() provides.

Cubbi
+1 -- it should be noted that timing based upon thread sleeps -- even nanosleep -- is unreliable at best.
Billy ONeal
+1  A: 

How about because your nanonsleep example is wrong.

#include <time.h>
...
struct timespec sleepTime;
struct timespec time_left_to_sleep;
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = 1000;
while( (sleepTime.tv_sec + sleepTime.tv_nec) > 0 )
{
   nanosleep(&sleepTime, &time_left_to_sleep);
   sleepTime.tv_sec = time_left_to_sleep.tv_sec;
   sleepTime.tv_msec = time_left_to_sleep.tv_nsec;
}

Admittedly if you're only sleeping for 1 microsecond waking up too early shouldn't be an issue, but in the general case this is the only way to get it done.

And just to ice the cake in boost's favor, boost::this_thread::sleep() is implemented using nanosleep(). They just took care of all the insane corner cases for you.

caspin
+1, I figured that boost `sleep()` would be implemented with `nanosleep()`, good to have confirmation.
Justin Ardini