Thread terminiert nicht

Alles rund um die Programmierung mit Qt
Antworten
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Thread terminiert nicht

Beitrag von Delryn »

Hallo,

ich kann mir gerade nicht erklären wieso mein QThread sich nicht beendet. Für jede Vermutung bin ich dankbar.

In der run()-Methode wird auf eine abort-Variable geprüft, so das mit break aus der while(true)-schleife gesprungen wird

Lösche ich jetzt meinen QThread, so sieht der Destruktor wie folgt aus

Code: Alles auswählen

if (isRunning())
{   
	Abort(); // Setzt die boolesche Variable m_Abort
}
       
       
wait(); // verursacht einfrieren
// Deletekram
Dann hab ich ein paar Ausgaben in die while(true)-Schleife gepackt, weil ich wissen wollte, wieso er sie nicht verlässt. Na ja, es wird in dieser Schleife eine reguläre von mir geschriebene Methode der Threadklasse aufgerufen:
while(true)
{
if(m_Abort)
{
emit VideoStopped();
break;
}

if(m_pImgSource)
{

if(!ReadNextFrame() ) // hier geht's nicht weiter
{
Wenn ich in ReadNextFrame nochmals auf !m_Abort prüfe und ggfs. sofort return(false) zurückliefere ändert das gar nichts.


Vlt. hat ja jemand so ermstal eine Idee dazu.
Mani99
Beiträge: 244
Registriert: 15. April 2009 10:46
Wohnort: München

Beitrag von Mani99 »

Vielleicht ist es hilfreich wenn du noch etwas mehr code zeigst als ein paar while schleifen?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Hab ich das richtig verstanden, du willst den Thread beenden indem du

Code: Alles auswählen

delete thread;
aufrufst? :shock:
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

pfid hat geschrieben:Hab ich das richtig verstanden, du willst den Thread beenden indem du

Code: Alles auswählen

delete thread;
aufrufst? :shock:

In der Klasse wo er benutzt wird hatte ich das vor. Im Destruktur wollte ich dann mit Abort() und wait() arbeiten, ich hab das jetzt aber in die Klasse die den Thread besitzt verlagert.

Dort sage ich quasi Abort() und dann wait(), damit er solange hängt bis die run-Methode beendet ist.

Danach sage ich delete thread.

Was noch zu beachten ist: Bei signal-Slot Geschichten kann es zu einem Hänger kommen, ich musste nochmal extra auf die Abort-Variable prüfen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Delryn hat geschrieben: Was noch zu beachten ist: Bei signal-Slot Geschichten kann es zu einem Hänger kommen, ich musste nochmal extra auf die Abort-Variable prüfen.
Ich würde eher sagen - da fehlt ein wenig C++ Kenntnisse und es funktioniert nur durch Zufall.

Code: Alles auswählen

while(true)
{
  if(m_Abort)
  {
    break;
  }
}
Der Compiler sieht hier dass sich innerhalb der Schleife m_Abort nie ändern kann. Deshalb wird sein Optimierungsalgorithmus ziemlich sicher auf die Idee kommen das ganze wegzuoptimieren.
Also entweder die Variable als 'volatile' deklarieren oder was gescheites mit einer QSemaphore zu machen...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

Christian81 hat geschrieben:
Delryn hat geschrieben: Was noch zu beachten ist: Bei signal-Slot Geschichten kann es zu einem Hänger kommen, ich musste nochmal extra auf die Abort-Variable prüfen.
Ich würde eher sagen - da fehlt ein wenig C++ Kenntnisse und es funktioniert nur durch Zufall.

Code: Alles auswählen

while(true)
{
  if(m_Abort)
  {
    break;
  }
}
Der Compiler sieht hier dass sich innerhalb der Schleife m_Abort nie ändern kann. Deshalb wird sein Optimierungsalgorithmus ziemlich sicher auf die Idee kommen das ganze wegzuoptimieren.
Also entweder die Variable als 'volatile' deklarieren oder was gescheites mit einer QSemaphore zu machen...

Warum sollte er das wegoptimieren?

m_Abort ist eine Membervariable der Klasse. Die kann ja sonstwo geändert werden. Z.B. von außen durch den Aufruf m_Abort.

Das funktioniert schon korrekt so.
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

An deiner Stelle würd ichs so machen:

Code: Alles auswählen

{
   while (!m_abort)
   {
      ...
   }
}

Code: Alles auswählen

void abort() { m_abort = true; }

Code: Alles auswählen

{
   myThread->abort();

   if (! myThread->wait(5))
      myThread->terminate();

   delete myThread;
}
Wenn du den Thread zu einem beliebigen Zeitpunkt einfach löscht, kannst du in Teufels küche kommen (in deinem kleinen Beispiel vielleicht nicht, aber wieso sollte mans nicht gleich richtig lernen...). Du solltest dem Thread a) signalisieren dass er sich zu beenden hat, b) warten bis er es getan und damit seine Ressourcen aufgeräumt hat, und c) ihn dann löschen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Delryn hat geschrieben: Das funktioniert schon korrekt so.
Na wenn Du meinst - viel Spass beim Bug-suchen :)

Und hier noch ein paar Infos für unserem C++-Experten: http://msdn.microsoft.com/en-us/library ... S.80).aspx
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

Christian81 hat geschrieben:
Delryn hat geschrieben: Das funktioniert schon korrekt so.
Na wenn Du meinst - viel Spass beim Bug-suchen :)

Und hier noch ein paar Infos für unserem C++-Experten: http://msdn.microsoft.com/en-us/library ... S.80).aspx
ich mache es fast so wie pfid es beschrieben hat. Wo ist dein Problem?

Nur das ich mit wait() wirklich so lange warte, bis der Thread sich terminiert hat.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Delryn hat geschrieben: ich mache es fast so wie pfid es beschrieben hat. Wo ist dein Problem?
Das das Beispiel von pfid genausowenig geht. Ist meine oder die Erklärung im msdn so unverständlich ???
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

Christian81 hat geschrieben:
Delryn hat geschrieben: ich mache es fast so wie pfid es beschrieben hat. Wo ist dein Problem?
Das das Beispiel von pfid genausowenig geht. Ist meine oder die Erklärung im msdn so unverständlich ???

Ja. Aber ich (und ich denke alle anderen auch) wäre dankbar, wenn du es nochmal erläutern würdest.

Imho lösen >90% die Threadgeschichte so wie pfid oder ich.
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Christian81 hat geschrieben:
Delryn hat geschrieben: ich mache es fast so wie pfid es beschrieben hat. Wo ist dein Problem?
Das das Beispiel von pfid genausowenig geht.
Erklär das mal bitte.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

pfid hat geschrieben:
Christian81 hat geschrieben:
Delryn hat geschrieben: ich mache es fast so wie pfid es beschrieben hat. Wo ist dein Problem?
Das das Beispiel von pfid genausowenig geht.
Erklär das mal bitte.
Stimmt - ich habe nicht gesehen wo Du m_abort definierst - steht dort ein 'volatile' ist alles ok. Steht dort keins muss es nicht unbedingt gehen. Siehe meine oberen Kommentare und den msdn-Link.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten