Спящий поток повышения на несколько наносекунд

Я хочу, чтобы поток ускорения заснул на несколько наносекунд. Следующий код является образцом, который компилируется без ошибок. Однако он не работает должным образом, и я не могу понять, почему.

#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;  
}

BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG — это определение препроцессора, необходимое для работы с наносекундами (подробнее). Проблемы возникают, когда я устанавливаю параметр построения -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG, тогда boost::this_thread::sleep не работает для любого posix::time_duration. Созданный поток использует весь ЦП, не спит и не обрабатывает оставшиеся инструкции. Если определение препроцессора удалено, поток может спать в течение любого периода времени, кроме boost::posix_time::nanoseconds. Программа использует некоторые переменные time_duration для хранения наносекунд, поэтому boost::this_thread::sleep не работает.

Спасибо вам большое за ваше время


person Emer    schedule 09.07.2011    source источник
comment
Что значит с ним не работает? Он спит слишком коротко или слишком долго или не спит вообще? Каков вывод строки std::cout с наносекундами?   -  person Nobody moving away from SE    schedule 09.07.2011
comment
Ты прав. Я отредактировал пост с лучшим описанием. Спасибо.   -  person Emer    schedule 11.07.2011
comment
Вы пробовали связать программу с отладочной информацией для буста и посмотреть, что происходит во время сна? Для меня это звучит как занятое ожидание, что ясно, поскольку нет другой возможности спать в течение наносекунд, потому что это намного ниже пределов планировщика. Возможно, ожидающий цикл никогда не возвращается по какой-то причине.   -  person Nobody moving away from SE    schedule 11.07.2011


Ответы (2)


BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG изменяет размер ptime.

boost::this_thread::sleep — это скомпилированная функция, которая была скомпилирована (в вашем дистрибутиве) без этого определения, поэтому она ожидает аргументы ptime с микросекундной точностью. Вы передаете аргументы ptime с точностью до наносекунды, и функция завершается ошибкой.

Если вы извлечете код из библиотеки boost и скомпилируете его с включенным определением, программа будет работать так, как ожидалось:

#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;
}
person Cubbi    schedule 11.07.2011
comment
(обратите внимание, что этот код предназначен только для демонстрации, поскольку мои мьютекс и переменная являются глобальными, тогда как в реальной библиотеке они являются нестатическими членами класса boost::thread) - person Cubbi; 11.07.2011
comment
Большое спасибо за ваш полезный ответ. Я пытаюсь создать библиотеку потоков с этим определением, используя b2. Я безуспешно добавил строку variant new_release : release : <define>BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG; к user-config.jam. Знаете ли вы, где включить параметр определения? - person Emer; 12.07.2011

Некоторые функции сна возвращаются раньше, когда их прерывают, поэтому вам нужно проверить возвращаемое значение функции и вызывать ее снова, пока они не вернут ноль.

person fwg    schedule 09.07.2011