boost threads
-
Hallo,
wer kennt sich mit boost threads aus?
Ich würde gerne boost threads in meiner Applikation verwenden. Nur habe ich ein kleines Problem. Ich möchte in einer Klasse den Thread als membervariable (evtl. als shared_ptr) erzeugen. Dieser soll von außerhalb (aus einer anderen klasse) beendet (also angehalten) und neu gestartet werden.
Angenommen ich habe einen boost::thread als shared pointer m_pthread:
Könnte es hier ein Problem geben?void thread_function() { while(!m_bStop) { } } void startThread() { if(!m_pthread) { m_bStop = false; m_pthread(new boost::thread(thread_function) } } void stopThread() { m_bStop = true; m_pthread->join() }Ich bin mir in einigen Dingen unsicher:
1. Ist das Starten des threads und das Stoppen richtig umgesetzt?
2. Wie stellt man fest, ob ein thread bereits erstellt ist?
3. Kann ich davon ausgehen, dass der heap nach dem join() und dem return aus der while schleife aufgeräumt ist?
3. Gibt es sonst noch Probleme, die euch einfallen?
4. Machen Shared Pointer hier überhaupt Sinn???Vielen Dank Euch und noch einen schönen Abend!
-
Wieso probierst Du es nicht einfach aus?
Ansonsten:
Ich würde nichtwhile(!stop), sondernwhile(running)benutzen.startThread()wird so nicht kompilieren,stopThread()ist so okay.- Am Besten gar nicht. Du kannst
boost::threaddirekt als Member Deiner Klasse benutzen. Wenn Du wissen willst, ob eine Funktion im Threadobjekt aktiv ist, kannst Du z.B.thread::joinable()befragen. - Wovon soll der Heap geräumt werden? Vom Threadobjekt? Siehe Punk 2.
- Nicht für diesen Codeschnippsel.
- Nein.
-
Da das Setzen/Lesen einer Variablen nicht unbedingt atomar sein muss empfehle ich statt des bools ein Event. Ich weiss leider nicht, ob boost so etwas anbietet/kapselt, aber mit der Win32 ginge das so:
class MyClass { HANDLE StopEvent_; public: MyClass() { StopEvent_ = CreateEvent( 0, // Security Attributes: use default TRUE, // manual reset FALSE, // initial state 0 ); // Name } ~MyClass() { if( StopEvent_ ) { CloseHandle( StopEvent_ ); } } void thread_function() { // Schleife durchlaufen, solange das Stopp Event nicht gesetzt ist while( WaitObject( StopEvent_, 0 ) != WAIT_OBJECT_0) { } } void start_thread() { if( StopEvent_ ) { // Stopp Event zurücksetzen ResetEvent( StopEvent_ ); ... } } void stop_thread() { if( StopEvent_ ) { // Stopp Event setzen SetEvent( StopEvent_ ); ... } } private: // Kopien verbieten MyClass( const MyClass& ); MyClass& operator=( const MyClass& ); };
-
DocShoe schrieb:
Da das Setzen/Lesen einer Variablen nicht unbedingt atomar sein muss...
Und das ist für die Run-Condition genau weshalb ein Problem? Vor allem, weil
join()als Barriere fungiert.
-
Das Problem an deinem Ansatz ist, dass in der Threadfunktion m_bStop nicht direkt verfügbar ist. Es sei denn, thread_function ist ein member einer Klasse, dan müsstes du dem Thread allerdings ein Funktionsobjekt übergeben, bei dem mit boost::bind das Klassenobjekt an die thread_function methode gebunden wurde.
Im Normalfall werden solche Benachrichtigungen für Threads über boost::conditionvariable_any gesteuert, die sind genau zu dem Zweck gedacht und ihre Änderungen sid auch atomar.
Alternativ kannst du dem Thread einen interrupt schicken, dann wird im Thread eine interrupt_exception geschmissen (nur an bestimmten Stellen). Wie das genau abläuft steht in der boost::thread doku.
-
Tachyon schrieb:
DocShoe schrieb:
Da das Setzen/Lesen einer Variablen nicht unbedingt atomar sein muss...
Und das ist für die Run-Condition genau weshalb ein Problem? Vor allem, weil
join()als Barriere fungiert.Kenn´ ich den ganzen Code der Thread Klasse? Vielleicht gibt es ja diese Methode:
bool is_running() const { return !m_bStop; }Damit lässt sich ein Fall konstruieren, in dem der Thread noch läuft, sich selbst aber als angehalten meldet.
-
Hallo,
eine Zwischenfrage sei mir gestattet...
was bedeutet denn "atomare Änderung"? Kann mir grad nichts darunter vorstellen...

Danke euch
Gruß
Jodi
-
J0di schrieb:
was bedeutet denn "atomare Änderung"? Kann mir grad nichts darunter vorstellen...

Das ist eine Änderung, welche komplett geschieht, ohne dass sie unterbrochen wird. Oftmals bestehen Betriebssystemspezifische Funktionen, um solche atomischen Veränderungen zu machen.
z.B findest du unter Windows sehr viele hier (die Interlocked Sachen):
http://msdn.microsoft.com/en-us/library/ms686360(v=VS.85).aspxWenn es kompliziertere Sachen sein sollen, dann kommst du um eigene Synchronisation nicht herum (Semaphore, Monitore usw.)