Seite 1 von 2

QThread: Funktionsweise

Verfasst: 7. Juli 2010 19:31
von Illuminatus
Hi ich habe den Blog über die korrekte Funktionsweise von QThreads gelsen, bin nun aber mehr verwirrt, als dass es geholfen hat. Es wird darauf verwiesen, dass man einen Thread nicht ableiten soll, sondern eine Instanz vom Typ QThread erzeugen soll und den Auftrag per movetoThread an den Thread weiterleitet.

Nun habe ich folgendes Problem: Ich parse mit einer CSVParser klasse und möchte das in einem Thread ausführen lassen, da das möglicherweise einige Zeit dauert und die GUI nicht blockiern soll.

Wie kann ich das mit der Instanz von QThread bewerkstelligen? movetoThread bekommt ja eine Instanz von QThread übergeben????


VG

Re: QThread: Funktionsweise

Verfasst: 7. Juli 2010 19:37
von franzf
Illuminatus hat geschrieben:Wie kann ich das mit der Instanz von QThread bewerkstelligen? movetoThread bekommt ja eine Instanz von QThread übergeben????
Ja, aber moveToThread ist eine Methode von QObject - du willst ja das Objekt in einen neuen Thread verschieben (eigentlich das Eventmanagement in die EventLoop des neuen Threads). Du musst also CSVParser von QObject ableiten. Aber pass auf, ein Funktionsaufruf geschieht immer im Context des aufrufenden Threads. Wenn deine CSVParser::start()-Methode selber rechnet, passiert das im Hauptthread. Wenn du das via moveToThread erledigen willst, muss das alles via SIGNAL/SLOTS resp. Events passieren.

Re: QThread: Funktionsweise

Verfasst: 7. Juli 2010 19:45
von Illuminatus
franzf hat geschrieben:
Illuminatus hat geschrieben:Wie kann ich das mit der Instanz von QThread bewerkstelligen? movetoThread bekommt ja eine Instanz von QThread übergeben????
Ja, aber moveToThread ist eine Methode von QObject - du willst ja das Objekt in einen neuen Thread verschieben (eigentlich das Eventmanagement in die EventLoop des neuen Threads). Du musst also CSVParser von QObject ableiten. Aber pass auf, ein Funktionsaufruf geschieht immer im Context des aufrufenden Threads. Wenn deine CSVParser::start()-Methode selber rechnet, passiert das im Hauptthread. Wenn du das via moveToThread erledigen willst, muss das alles via SIGNAL/SLOTS resp. Events passieren.
Also muss ich in der Instanz von CSVParser , also pratkisch bevor ich die ganze Arbeit (parsen) mache, movetoThread(*meinAuslagerungsThread) aufrufen?

und ich versteh nicht ganz wie du meinst bezüglich der start() oder SIGNAL/SLOT?

Re: QThread: Funktionsweise

Verfasst: 7. Juli 2010 22:02
von solarix
Illuminatus hat geschrieben: Also muss ich in der Instanz von CSVParser , also pratkisch bevor ich die ganze Arbeit (parsen) mache, movetoThread(*meinAuslagerungsThread) aufrufen?
Es gibt viele Wege.. angenommen du hast in der GUI eine private Variabel "CSVParser *mParser" und einen im CTor aufgesetzen Threadkontext (QThread *mThread), könnte die Initialisierung so in etwa wie folgt aussehen:

Code: Alles auswählen

  mParser = new CSVParser(filename);
  mParser->moveToThread(mThread);

  // jetzt möchtest du noch wissen, wann die Arbeit fertig ist:
  connect(mParser, SIGNAL(done()), this, SLOT(.....));
Illuminatus hat geschrieben: und ich versteh nicht ganz wie du meinst bezüglich der start() oder SIGNAL/SLOT?
Was franz meint ist, dass du über ein SIGNAL (aus dem GUI-Kontext) die Arbeit aktivieren musst.. dies könnte ein Signal "clicked()" eines QPushButtons sein oder aber auch mit einem Signal geschehen, welches sich der Parser selbst sendet, also so in etwa:

Code: Alles auswählen

   // in der GUI:
   .... initialisierung
   mParser->start();

  // in der Parserklasse:
  void CSVParser::start() 
  {
    emit startParser();
  }
"startParser()" ist dann verbunden mit einem private Slot von CSVParser und führt diesen damit im Thread-Kontext aus.

hth..

Verfasst: 7. Juli 2010 23:17
von Illuminatus
Ah perfekt! ich glaube ich hab verstanden was ihr meint! werde das gleich mal morgen ausprobieren!

Vielen Dank für eure hilfe!

Verfasst: 9. Juli 2010 20:12
von bbt
Wie kann man dann so einen Thread am besten unterbrechen?

Verfasst: 12. Juli 2010 10:51
von solarix
Wie jeden anderen Thread... ist ja egal, ob es die Methode "Mythread::run()" (von QThread geerbt) ist oder "Worker::doWork()" (von QObject geerbt).

Verfasst: 13. Juli 2010 19:22
von Illuminatus
Muss ich auf irgendwelche speziellen Dinge achten bezüglich der Speicherfreigabe durch den Thread?

Verfasst: 18. Juli 2010 14:17
von Illuminatus
Wie kann ich den Thread Speicher resetten, also einfach Destrutkor aufrufen?

Verfasst: 18. Juli 2010 14:27
von Christian81
Ein QThread ist wie ein ganz normales Objekt - delete löscht es. Man sollte allerdings darauf achten dass der Thread nicht mehr läuft wenn man ihn löscht.

Verfasst: 18. Juli 2010 15:52
von Illuminatus
Muss man den Thread Threadkontext (QThread *mThread) auch starten?

Verfasst: 18. Juli 2010 16:13
von Christian81
Illuminatus hat geschrieben:Muss man den Thread Threadkontext (QThread *mThread) auch starten?
Was meinst Du damit? Ob man QThread::start() aufrufen muss?

Verfasst: 18. Juli 2010 16:19
von Illuminatus
Ich hab Probleme das Beispiel von Solarix zu verstehen -.-

Ich dachte ich muss eine "start Methode" in meiner Parser klasse schreiben, die an den ThreadContext übergeben und dann die start() meiner CSV KLasse aufrufen

Verfasst: 18. Juli 2010 16:22
von Christian81
Ob mans glaubt oder nicht aber in der Doku steht haargenau was Du implementieren musst und wie Du den Thread startest...

Verfasst: 18. Juli 2010 16:24
von Illuminatus
Ja aber laut dem Post vor einigen Tagen, is das der "falsche weg" einen thread zu implementieren oder hab ich das falsch verstanden??? Ich kann die doku nicht mit dem movetothread zusammenbringen