2011-07-09 4 views
6

Chcę wątku doładowania do spania przez kilka nanosekund. Poniższy kod jest próbką kompilującą bez błędów. Jednak nie działa zgodnie z oczekiwaniami i nie mogę zrozumieć, dlaczego.Spanie wątku doładowania przez kilka nanosekund

#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 jest definicją preprocesor wymagane w celu współpracy z nanosekund (more info). Problemy pojawiają się, gdy ustawiam opcję budowania -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG, wtedy boost :: this_thread :: sleep nie działa dla żadnego posix :: time_duration. Utworzony wątek wykorzystuje cały procesor i nie śpi ani nie przetwarza pozostałych instrukcji. Jeśli definicja preprocesora zostanie usunięta, wątek może zostać uśpiony na dowolny okres czasu, chyba że funkcja boost :: posix_time :: nanoseconds. Program używa zmiennych time_duration do przechowywania nanosekund i sprawia, że ​​boost :: this_thread :: sleep nie działa.

Dziękuję bardzo za poświęcony czas

+1

Co masz na myśli z nim nie działa? Czy śpi krótko, czy długo, czy wcale? Jakie jest wyjście linii std :: cout z nanosecs? – Nobody

+0

Masz rację. Edytowałem post z lepszym opisem. Dziękuję Ci. – Emer

+0

Czy próbowałeś połączyć program z debuginformacją, aby zwiększyć i sprawdzić, co dzieje się podczas snu? Dla mnie brzmi to jak pełne oczekiwania, co jest jasne, ponieważ nie ma innej możliwości spania przez nanosekundy, ponieważ jest to znacznie poniżej limitów harmonogramów. Być może oczekująca pętla nigdy nie wraca z jakiegoś powodu. – Nobody

Odpowiedz

7

Numer BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG zmienia rozmiar .

boost::this_thread::sleep to skompilowana funkcja, która została skompilowana (w twojej dystrybucji) bez tej definicji, więc oczekuje wartości mikrosekundowej precyzji ptime. Przekazujesz nanosekundowe precyzyjne argumenty ptime, a funkcja kończy się niepowodzeniem.

Jeśli wyodrębnić kod z biblioteki Boost i skompilować je definiują to włączone, program działa zgodnie z oczekiwaniami:

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

(zauważ, że ten kod jest tylko demo, ponieważ mój muteks i condvar są globalne, podczas gdy w prawdziwej bibliotece są niestatycznymi członkami klasy boost :: thread). – Cubbi

+0

Dziękuję bardzo za pomocną odpowiedź. Próbuję zbudować bibliotekę wątków z tą definicją za pomocą 'b2'. Dodałem wiersz 'variant new_release: release: BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG;' do 'user-config.jam' bez powodzenia. Czy wiesz, gdzie umieścić opcję define? – Emer

2

Niektóre funkcje snu powrócić wcześnie kiedy interupted więc trzeba sprawdzić wartość zwracaną przez funkcję i wywołać ją ponownie, aż do ich powrotu do zera.