2010-12-16 8 views
9

Ich benutze die boost :: thread library (V1.44) um Threads in meinem C++ Projekt zu unterstützen.Einen boost :: thread für unbegrenzte Zeit anhalten

Der Benutzer muss in der Lage sein, die Ausführung einer Testschleife, die in einem eigenen Thread ausgeführt wird, für eine unbegrenzte Zeit zu unterbrechen und in der Lage zu sein, es wann immer er will fortzusetzen.

unter Windows Ich löste es wie diese

bool ContintueLoop(){ 
if(testLoopPaused){ //testLoopPaused can be set by the user via GUI elements 
    try{ 
     boost::this_thread::interruptible_wait(2147483648); //that's very ugly, 
     // somebody knows the right way to pause it for a unlimited time? 
     return true; 
    } 
    catch(boost::thread_interrupted& e){ //when the user selects resume the 
     // the thread is interrupted and continues from here 
     testLoopPaused = false; 
     return true; 
    } 
if(...) //test for other flags like endTestLoop etc. 
    .... 
} 

Dies ohne Probleme funktioniert, obwohl es schön wäre, um den richtigen Wert für eine unbegrenzte Unterbrechung zu kennen.

begann ich eine Linux-Version meines Programms zu implementieren, aber ich lief in das Problem , dass ich den Compiler-Fehler

error: interruptible_wait is not a member of boost::this_thread

Frage bekommen: Was eine gute Möglichkeit ist, einen Schub zu pausieren :: thread für eine unbegrenzte Zeit (bis der Benutzer sie wieder aufnehmen entscheidet)

Vielen Dank

+0

Gibt es keinen Befehl wie 'Suspend()'? –

+0

@sad_man, nein gibt es nicht. Es gibt eine Sleep-Funktion, die den Thread für eine definierte Zeitspanne aussetzt, aber ich glaube nicht, dass der unterbrochene Thread zu einer zufälligen Zeit wieder aufgenommen werden kann. – zitroneneis

Antwort

18

ich bin mir nicht bewusst keine Weise ein Gewinde an einem beliebigen Punkt mit boost :: thread zu pausieren, Die von Ihnen beschriebene Situation kann jedoch mithilfe einer booleschen, Mutex- und Bedingungsvariablen implementiert werden.

bool m_pause; // initialise to false in constructor! 
boost::mutex m_pause_mutex; 
boost::condition_variable m_pause_changed; 

void block_while_paused() 
{ 
    boost::unique_lock<boost::mutex> lock(m_pause_mutex); 
    while(m_pause) 
    { 
     m_pause_changed.wait(lock); 
    } 
} 

void set_paused(bool new_value) 
{ 
    { 
     boost::unique_lock<boost::mutex> lock(m_pause_mutex); 
     m_pause = new_value; 
    } 

    m_pause_changed.notify_all(); 
} 

in Ihrem Arbeitsthread So können Sie in regelmäßigen Abständen block_while_paused() aufrufen, die es wird bestätigt, bis m_pause auf false gesetzt ist. In Ihrem Hauptthread rufen Sie set_paused(value) auf, um den Wert der Pausenvariablen threadsicher zu aktualisieren.

Haftungsausschluss: Diese ist aus einem ähnlichen Code, den wir hier haben angepasst, aber ich habe nicht zu kompilieren, den angepassten Code versucht, geschweige denn überprüfen tatsächlich funktioniert :)

+0

@Adam, das sieht sehr vielversprechend aus. Ich werde versuchen, es umzusetzen und zu berichten, danke! – zitroneneis

+0

Wenn Sie eine Art von Klasse haben, die Ihren Worker-Thread repräsentiert, ist es am besten, all das in die Klasse zu legen und alles außer 'set_paused' privat zu machen, damit es nicht missbraucht werden kann. Das einzige, was zu beachten ist, dass 'mutex' und' condition_variable' nicht kopiert werden können, was (je nachdem, wie du deinen Thread mit Boost erstellst) eine leichte Unannehmlichkeit sein kann. –

+0

Jetzt nur in eine Warteschlange und Sie können den Thread vollständig kontrollieren;) @ Adam: kleine Bemerkung, Sie müssen nicht auf Notify_all() entsperren, was Ihren Code ein wenig vereinfachen würde. – stefaanv

1

Wenn jemand muss noch erwähnt Funktionalität (Schlafgewinde bis ein Ereignis eintritt) und ist bequem mit Boost-Bibliotheken dann Boost.Interprocess Bibliothek bietet Semaphore Mechanismus, der wie beschrieben in Frage verwendet werden kann.

Verwandte Themen