QThread und EventLoop ohne exec()

Code-Schnippsel, oder Tipps und Tricks, die einem beim Programmieren mit Qt helfen können.
Antworten
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

QThread und EventLoop ohne exec()

Beitrag von CaptnChaos »

Ich hasse QThreads. Sie sind zwar ein schöner Wrapper um Threading, die es ermöglicht objektorientiert zu programmieren, zwingen mich jedoch dazu alles innerhalb des Threads per Timer und oder Events zu regeln.
Solange sich der Thread auf Aufgaben beschränkt die Mittels Qt-Eigenen Klassen gelöst werden können stört das nicht weiter. Möchte man jedoch einen Thread basteln der eben nicht nur mit signals und slots auskommt ist man ohne Trickserei schnell am Ende.
Das musste ich schmerzlich feststellen als ich QExtSerial mit Timeout in einem Thread realisieren wollte. Für das Timeout brauchte ich einen Timer, der Timer aber eine EventLoop, die serielle Kommunikation muss jedoch gepollt werden was das Aufrufen von exec() nicht erlaubt.

Der Thread braucht eine EventLoop um mit einem QTimer was anfangen zu können, jedoch muss die Funktion zum Übertragen und Empfangen von Daten so oft wie möglich aufgerufen werden.
Die Koexistenz der unendlichen EventLoop sowie einer zweiten unendlichen Funktion sieht so aus:

Code: Alles auswählen

void MyThread::run()
{
    QEventLoop el;
    while(1){
        funktion(); // Hier werden die Daten gelesen und geschrieben
                        // oder eine andere Aufgabe verrichtet, die nicht oder 
                        // umständlich realisiert werden kann
        el.processEvents(); // Events pollen
}
    }
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

wie wuerdest du nen Timer aufziehen ohne die QT(thread) ?
Was hindert Dich es unter der QT nich genau so zu machen ?

BTW, nur wegen dem timer den thread in ne QT Loop laufen lassen faende ich auch recht unschoen gelöst !

Ciao ....
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Falls du mit "QExtSerial" die Klasse "QextSerialPort" meinst, frage ich mich wo das Problem liegt:

Wenn du pollen und einen QTimer als Timeout einsetzen möchtest, brauchst du keinen Thread (das Pollen über einen zweiten QTimer geht auch in der GUI).
Wenn du einen Thread hast kannst du ja blockierende Aufrufe nehmen:

Code: Alles auswählen

 {
    serial.write(....);
    if (serial.waitForReadyRead(timeout)) {
      serial.read(....);
      ..
    }
 }
Im Beispielcode fehlt natürlich noch die Protokollbehandlung (was tun wenn erst die Hälfte der Antwort angekommen ist). Aber das muss sowieso gelöst werden (egal ob Polling oder blockierendes Lesen).

hth...
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

Das mit dem seriellen Protokoll war nur ein Beispiel. Es gibt andere Anwendungsfälle.
Die Lösung per QTimer zu pollen ist unschön. ich müsste den Timer ziemlich schnell laufen lassen um einer Baud von 115200 gerecht zu werden, was der Leistung meiner Anwendung nicht unbedingt zugute kommt bzw unter Umständen nicht richtig funktioniert. Ja, ein Timeout kann ich auch mit waitForReadyRead realisieren jedoch wird der Rest meines Programms währenddessen geblockt und es ist wieder umständlich mehrere Versuchsinstanzen zu implementieren.
Aber das ist ein anderes Thema. Es geht ja eigentlich nur um die Tatsache wie man eine EventLoop nebenher laufen lässt statt exec aufzurufen und damit eine EventLoop zur Hauptaufgabe des Threads zu machen.

@RHBaum
BTW, nur wegen dem timer den thread in ne QT Loop laufen lassen faende ich auch recht unschoen gelöst !
Ein normaler QThread besteht aus nichts anderem als einer EventLoop. Jedenfalls ist es so von den Entwicklern gewünscht.
So sollen QThreads eigentlich verwendet werden.
Ich lasse den Thread also nicht in eine EventLoop laufen sondern neben der eigentlichen Aufgabe des Threads wird eine EventLoop laufen gelassen um weiterhin Qt-Features wie QTimer nutzen zu können.
Antworten