2013-07-08 10 views
6

Użyłem gcc-4.8.1 (configure: ./configure --prefix =/usr/local) do skompilowania następującego kodu w Ubuntu 12.04, ale kiedy go uruchomiłem, to nie zadziałało. nie przestawał czekać na muteksa. Zwrócił wartość false i wyświetlił komunikat "Witaj, świecie!"Dlaczego std :: timed_mutex :: try_lock_for nie działa?

polecenie: g ++ -std = C++ 11 main.cpp -omain -pthread

Kiedy użyłem gcc-4.6 (apt-get install g ++), aby go skompilować, to działa dobrze. Program czekał około dziesięciu sekund i wyświetlił "Hello world!"

#include <thread> 
#include <iostream> 
#include <chrono> 
#include <mutex> 

std::timed_mutex test_mutex; 

void f() 
{ 
    test_mutex.try_lock_for(std::chrono::seconds(10)); 
    std::cout << "hello world\n"; 
} 

int main() 
{ 
    std::lock_guard<std::timed_mutex> l(test_mutex); 
    std::thread t(f); 
    t.join(); 
     return 0; 
} 

Odpowiedz

6

Jeśli się nie mylę, to Bug 54562 -mutex and condition variable timers.

Przyczyną błędu jest również wymienić:

To dlatego, że używa CLOCK_MONOTONIC zegar (jeśli są dostępne na platformie ) obliczyć czas bezwzględny, gdy jest konieczne do powrotu, który jest nieprawidłowy ponieważ POSIX pthread_mutex_timedlock() wywołanie używa zegar CLOCK_REALTIME, a na mojej platformie zegar monotoniczny jest sposób za zegarem czasu rzeczywistego.

Jednak to nie wyjaśnia, dlaczego widzisz prawidłowe zachowanie na gcc-4.6 jednak. Być może _GLIBCXX_USE_CLOCK_MONOTONIC nie jest włączony?

+0

Dzięki, gdy wyłączyłem _GLIBCXX_USE_CLOCK_MONOTONIC, gcc-4.8 i gcc-4.6 zachowują się tak samo. I myślę, że powodem, dla którego mają inne zachowanie, jest to marco. – miskcoo

+1

Dla każdego, kto chce uaktualnić gcc/g ++ do 4.9 (tam, gdzie naprawiono błąd), postępuj zgodnie z [tymi instrukcjami] (http://superuser.com/a/394811/235047) dla Ubuntu, zastępując '4.6' "4.9". – Garrett

+0

Jak włączyć _GLIBCXX_USE_CLOCK_MONOTONIC? – SomethingSomething

0

Możliwe obejście:

const int WAIT_PRECISION_MS = 10; // Change it to whatever you like 
int TIME_TO_WAIT_MS = 2000;  // Change it to whatever you like 
int ms_waited = 0; 
bool got_lock = false; 
while (ms_waited < TIME_TO_WAIT_MS) { 
    std::this_thread::sleep_for(
          std::chrono::milliseconds(WAIT_PRECISION_MS)); 
    ms_waited += WAIT_PRECISION_MS; 
    got_lock = YOUR_MUTEX.try_lock(); 
    if (got_lock) { 
     break; 
    } 
} 

WAIT_PRECISION_MS powie pętli while, jak często się „obudzić” i starają się zamek. Ale wskazywałby także, jak dokładny będzie Twój termin, chyba że twój dokładny czas jest czynnikiem czasu ostatecznego.

Na przykład:

deadline = 20, precyzja = 3: 3 nie jest czynnikiem 20 - ostatni iteracji pętli while będzie, gdy ms_waited jest 18. Oznacza to, że jesteś będzie czekać w sumie 21 ms, a nie 20 ms.

deadline = 20, precyzja = 4: 4 jest czynnikiem 20 - ostatni iteracji pętli while będzie, gdy ms_waited wynosi 16. Oznacza to, że masz zamiar czekać dokładnie 20ms, jako swój termin jest określony.