2013-07-08 7 views
6

Ich habe gcc-4.8.1 (configure: ./configure --prefix =/usr/local) verwendet, um folgenden Code in Ubuntu 12.04 zu kompilieren, aber als ich es ausführte, funktionierte es nicht. es hörte nicht auf den Mutex zu warten. Es wurde falsch zurückgegeben und "Hallo Welt!"Warum funktioniert std :: timed_mutex :: try_lock_for nicht?

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

Als ich noch gcc-4.6 (apt-get install g ++), es zu kompilieren, ist es gut funktioniert. Das Programm wartete etwa zehn Sekunden und gab "Hallo Welt!"

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

Antwort

6

Wenn ich mich nicht täusche, ist, dass Bug 54562 -mutex and condition variable timers.

Der Grund für den Fehler ist auch erwähnt:

Dies ist, weil es die CLOCK_MONOTONIC Uhr verwendet (falls vorhanden auf der -Plattform) die absolute Zeit zu berechnen, wenn es zurückgeben muß, was falsch ist wie der POSIX pthread_mutex_timedlock() Aufruf verwendet die Uhr CLOCK_REALTIME, und auf meiner Plattform ist die monotone Uhr Weg hinter der Echtzeituhr.

Dies erklärt jedoch nicht, warum Sie das richtige Verhalten auf gcc-4.6 obwohl sehen. Vielleicht ist _GLIBCXX_USE_CLOCK_MONOTONIC nicht aktiviert?

+0

Danke, wenn ich _GLIBCXX_USE_CLOCK_MONOTONIC deaktivieren, haben gcc-4.8 und gcc-4.6 das gleiche Verhalten. Und ich denke, dass der Grund, warum sie ein anderes Verhalten haben, dieser Marco ist. – miskcoo

+1

Für alle, die gcc/g ++ auf 4.9 upgraden möchten (wo der Fehler behoben wurde), folgen Sie [diesen Anweisungen] (http://superuser.com/a/394811/235047) für Ubuntu, ersetzen Sie einfach '4.6' mit "4.9". – Garrett

+0

Wie aktivieren Sie _GLIBCXX_USE_CLOCK_MONOTONIC? – SomethingSomething

0

Eine mögliche Abhilfe:

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

Die WAIT_PRECISION_MS wird die while-Schleife sagen, wie oft zu „wecken“ und versuchen, die Sperre zu bekommen. Aber es würde auch zeigen, wie genau Ihre Deadline sein wird, es sei denn, Ihre Genauigkeitszeit ist ein Faktor der Deadline-Zeit.

Zum Beispiel:

Frist = 20, Präzision = 3: 3 ist kein Faktor 20 - die letzte Iteration der while-Schleife sein wird, wenn ms_waited ist 18. Es bedeutet, dass Sie warten insgesamt 21ms und nicht 20ms.

Frist = 20, Präzision = 4: 4 ist ein Faktor 20 - die letzte Iteration der while-Schleife sein wird, wenn ms_waited ist 16. Das bedeutet, dass Sie genau 20ms warten wollen, wie Ihre Deadline ist definiert.

Verwandte Themen