2012-04-05 10 views
2

Ich bin in einem Worker-Thread und möchte für eine bestimmte Zeit (in der Regel ein paar hundert Millisekunden) schlafen, aber der Schlaf sollte unterbrechbar sein. Hier ist, was ich habe kommen mitUnterbrechbarer Schlaf in Qt?

void DummyScope::sleepForSamples() { 
    if(m_sampleSleep < 100) { 
     MySleeper::sleep(m_sampleSleep); 
     return; 
    } 

    // sleep in periods of 100 ms, to be responsible for shutdown requests  
    qint64 t = QDateTime::currentMSecsSinceEpoch(); 
    qint64 end = t + m_sampleSleep; 

    while(t + 100 <= end) { 
     MySleeper::sleep(100); 
     t = QDateTime::currentMSecsSinceEpoch(); 

     // TODO: check here whether we are interrupted 
    } 

    if(end > t) { 
     MySleeper::sleep(end - t); 
    } 
} 

jedoch, die ein bisschen verworren aussieht und ich frage mich, ob es einen besseren Weg, dies zu tun. Verwenden Sie eine QWaitCondition mit einer Zeitüberschreitung - warten Sie eine bessere Lösung?

Antwort

2

'Verwendet eine QWaitCondition mit einem Timeout - warten Sie eine bessere Lösung?'

Ja!

Die sleep() - Schleife, abgesehen von unnötigerweise alle 100 ms, hat eine durchschnittliche "Interrupt" -Latenz von 50 ms.

+0

Können Sie bitte eine Begründung/etwas Hintergrund geben? Dinge wie Wartezustände und Mutexe klingen wie schweres POSIX-Zeug. Im Gegensatz dazu gibt es in meiner Schleife nur grundlegende Schläfchen. –

+0

Sie benötigen keinen Mutex, nur 'wenn QWaitCondition :: wait (timeout)'. –

+0

@ JohannesSchaub-litb Ich denke, es ist, weil mit einem Timer Ihr Prozess nie aufwacht, stattdessen ist es der OS-Scheduler, der erkennt, wenn Ihr Prozess unterbrochen werden muss. Dies hat auch eine bessere Latenz. Bei Ihrer Schleife wird eine durchschnittliche Latenzzeit von 2 auftreten, bevor Sie aufwachen, um ein Ereignis zu verarbeiten. – sashoalm

0

Warten Sie auf eine Bedingungsvariable und lassen Sie sich in dem begleitenden Zustand darüber informieren, warum Sie unterbrochen wurden.
Wenn Sie keine QT-Threads verwenden müssen, können Sie mit C++ 11 und boost ein Prädikat zu wait_for/timed_wait hinzufügen, damit falsche Wakeups nicht mit Ihrem Timeout verwechselt werden.

Natürlich ist es noch komfortabler, wenn Sie 1 Schritt weiter gehen und sich nicht mit einem Timeout belästigen lassen (wenn die Zustandsvariable alle Fälle behandeln kann).

+0

@ JohannesSchaub-litb: Ich habe nur gerade über das Prädikat in Boost/C++ 11 übergeben (wenn das ist die Spur Wakeup, die Sie fragen). Qt (und andere Implementierungen, die ich kenne) haben es nicht. – stefaanv

0

Sie können direkt auf den Mutex mit QMutex::tryLock(int timeout) warten, wenn Sie es von einem anderen Thread sperren und entsperren.