Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sleeping a boost thread for some nanoseconds

I want a boost thread to sleep for some nanoseconds. The following code is a sample that compiles without errors. However, it does not work as expected and I cannot figure out why.

#include <iostream>  
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time.hpp>
//Building options:
//-DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG -lboost_date_time-mt -lboost_thread-mt 
void replay()  
{
    boost::posix_time::time_duration time1, time2; 

    time1=boost::posix_time::seconds(3);
    std::cout << boost::posix_time::to_simple_string(time1) << std::endl;
    boost::this_thread::sleep(time1);

    time2=boost::posix_time::nanoseconds(987654321);
    std::cout << boost::posix_time::to_simple_string(time2) << std::endl;
    boost::this_thread::sleep(time2); 
}
int main(int argc, char* argv[])  
{  
    boost::thread replaythread(replay);  
    replaythread.join();
    return 0;  
}

The BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG is a preprocessor definition required in order to work with nanoseconds (more info). The problems occurs when I set the -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG building option, then the boost::this_thread::sleep does not work for any posix::time_duration. The created thread uses all the CPU and it does not sleep nor process the remaining instructions. If the preprocessor definition is removed, the thread can sleep for any time period unless boost::posix_time::nanoseconds. The program uses some time_duration variables to store nanoseconds and that makes the boost::this_thread::sleep not work.

Thank you very much for your time

like image 817
Emer Avatar asked Jul 09 '11 18:07

Emer


2 Answers

The BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG changes the size of ptime.

boost::this_thread::sleep is a compiled function, which was compiled (on your distro) without that define, so it expects microsecond-precision ptime arguments. You're passing nanosecond-precision ptime arguments, and the function fails.

If you extract the code from the boost library and compile it with this define enabled, the program works as expected:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time.hpp>

// the guts of boost_1_46_1/libs/pthread/thread.cpp's version of sleep()
boost::mutex sleep_mutex;
boost::condition_variable sleep_condition;
void mysleep(const boost::posix_time::time_duration& dur)
{
    boost::system_time st = boost::get_system_time() + dur;
    boost::unique_lock<boost::mutex> lk(sleep_mutex);
    while(sleep_condition.timed_wait(lk, st));
}

void replay()
{
    boost::posix_time::time_duration time1, time2;

    time1=boost::posix_time::seconds(3);
    std::cout << boost::posix_time::to_simple_string(time1) << std::endl;
    mysleep(time1);
    //boost::this_thread::sleep(time1);

    time2=boost::posix_time::nanoseconds(987654321);
    std::cout << boost::posix_time::to_simple_string(time2) << std::endl;
    mysleep(time2);
    //boost::this_thread::sleep(time2);
}
int main()
{
    boost::thread replaythread(replay);
    replaythread.join();
    return 0;
}
like image 65
Cubbi Avatar answered Sep 27 '22 21:09

Cubbi


Some sleep functions return early when interupted so you have to check the return value of the function and call it again until they return zero.

like image 45
fwg Avatar answered Sep 27 '22 20:09

fwg