Search code examples
c++sleepboost-thread

C++ boost sleep accuracy


I'm experiencing strange issues with boost::sleep() function. I have this basic code:

#include <sys/time.h>
#include <boost/chrono.hpp>
#include <boost/thread.hpp>

void thread_func()
{
    timeval start, end;
    gettimeofday( &start, NULL );
    boost::this_thread::sleep( boost::posix_time::milliseconds(1) ); // usleep(1000) here works just fine.
    gettimeofday( &end, NULL );

    int secs = end.tv_sec - start.tv_sec;
    int usec = end.tv_usec - start.tv_usec;
    std::cout << "Elapsed time: " << secs << " s and " << usec << " us" << std::endl;
}

int main()
{
    thread_func();

    boost::thread thread = boost::thread( thread_func );
    thread.join();

    return 0;
}

The problem is that the boost::sleep() functions behaves differently in the created thread and in the main one. The output of this program is

Elapsed time: 0 s and 1066 us
Elapsed time: 0 s and 101083 us

i.e. the boost::sleep() function sleeps for 100 milliseconds in the created thread, whereas it works okay in the main thread (it sleeps for 1 ms). If I'm inside a created thread, I can't get the accuracy below 100 ms (for example by using boost::posix_time::microseconds). However, if I use usleep(1000), it works just fine.

I'm using Fedora 18 (64-bit) 3.8.4 & Boost 1.50.0-5.fc18 on Intel i7 CPU. I also tested the code on different PC with Win 7 & Boost 1.48.0 and the problem does not occur, so I guess it should be related to the system configuration, but I have no clue how.


Solution

  • boost::this_thread::sleep is deprecated (see docs).

    usleep is also deprecated (obsolete in POSIX.1-2001 and removed from POSIX.1-2008).

    FWIW, in the older (1.44) boost headers I have installed locally, the relative delay version of boost::this_thread_sleep actually calls gettimeofday to calculate the absolute deadline, and then forwards to the absolute version (which is compiled out-of-line, so I don't have it handy). Note that gettimeofday was also marked obsolete in POSIX.1-2008.

    The suggested replacements for all these are:

    • boost::this_thread::sleep_for instead of ...::sleep with a relative delay
    • boost::this_thread::sleep_until instead of ...::sleep with an absolute time
    • nanosleep instead of usleep
    • clock_gettime instead of gettimeofday