QSockets, QThreads, Non-Blocking auf die Daten warten
Verfasst: 1. März 2007 22:36
Grüßgottle,
ich habe Schwierigkeiten mit der Handhabung von QSockets in Verbindung mit QThreads (Beides Qt 2.3). Ich versuche mal, mein Problem zu erklären, bei Bedarf schicke ich gerne Quellcode mit.
Beschreibung
Ich habe eine Client-Klasse mit einem QSocket. Normalerweise schicke ich über das Socket eine Anfrage an den Server, er soll mir bitte 3D-Daten schicken (die ich dann später auf dem Client darstellen möchte).
Dann passiert kurz nichts, bis die Daten kommen. Kurze Zeit später wird automatisch das Signal "readyRead()" aufgerufen, weil die Daten beim Socket 'anklopfen'. Daraufhin rufe ich beim Client eine read()-Methode auf, die die Daten einliest. Diese wird meist mehrmal aufgerufen, weil die Daten für einen Schub zu groß sind.
Das Problem
So weit so gut.
Nun möchte ich aber immer neue 3D-Daten einlesen (und diese teilweise gegen alte austauschen), gleichzeitig aber die schon vorhandenen Daten darstellen.
Ich öffne also einen neuen Thread. Da muss man dann synchronisieren und so weiter (ich behaupte mal das wäre erledigt).
Jetzt kommt meine Frage:
Mit meinem neuen Thread schicke ich eine Anfrage für die neuen 3D-Daten, die ich gerade benötige.
Weil ich unbedingt warten muss, bis alle neuen Daten vollständigig eingelesen sind, bevor ich in diesem Thread fortfahren darf (damit ich keine inkonsistenten Zustände kriege), schreibe ich ein:
a)
b)
c)
Leider tut's nicht
Ist aber alles nicht so geschickt, denn
bei c) blockiert der Thread, es ist also ein "busy waiting". Während des wartens kann sonst niemand was tun.
Bei b) könnten meines Erachtens andere Threads weiterarbeiten. Wenn ich dann immer mit qsocket.bytesAvailable() gucke, ob schon was da ist, verschwenden wir nicht viel Zeit.
Aber: So lange man schläft, wird kein Signal "readyRead()" emmitiert. Nix kommt am Socket an, komischerweise.
Bei a) Lande ich in einem Deadlock. Auch hier kommt nichts mehr am socket an, daher kann man die QWaitCondition nicht mehr lösen.
Zugegeben, die drei Vorschläge erscheinen mir selbst auch noch nicht besonders hübsch, bisher fiel mir aber nichts anderes ein.
Gibt es tolle Ideen/Musterbeispiele/Standardlösungen?
Kommen jemandem die Probleme bekannt vor?
Vielen Dank im Voraus,
Niklas
[/b]
ich habe Schwierigkeiten mit der Handhabung von QSockets in Verbindung mit QThreads (Beides Qt 2.3). Ich versuche mal, mein Problem zu erklären, bei Bedarf schicke ich gerne Quellcode mit.
Beschreibung
Ich habe eine Client-Klasse mit einem QSocket. Normalerweise schicke ich über das Socket eine Anfrage an den Server, er soll mir bitte 3D-Daten schicken (die ich dann später auf dem Client darstellen möchte).
Dann passiert kurz nichts, bis die Daten kommen. Kurze Zeit später wird automatisch das Signal "readyRead()" aufgerufen, weil die Daten beim Socket 'anklopfen'. Daraufhin rufe ich beim Client eine read()-Methode auf, die die Daten einliest. Diese wird meist mehrmal aufgerufen, weil die Daten für einen Schub zu groß sind.
Das Problem
So weit so gut.
Nun möchte ich aber immer neue 3D-Daten einlesen (und diese teilweise gegen alte austauschen), gleichzeitig aber die schon vorhandenen Daten darstellen.
Ich öffne also einen neuen Thread. Da muss man dann synchronisieren und so weiter (ich behaupte mal das wäre erledigt).
Jetzt kommt meine Frage:
Mit meinem neuen Thread schicke ich eine Anfrage für die neuen 3D-Daten, die ich gerade benötige.
Weil ich unbedingt warten muss, bis alle neuen Daten vollständigig eingelesen sind, bevor ich in diesem Thread fortfahren darf (damit ich keine inkonsistenten Zustände kriege), schreibe ich ein:
a)
Code: Alles auswählen
qwaitcond.wait()Code: Alles auswählen
usleep(1000);Code: Alles auswählen
qsocket.waitForMore(1000);Ist aber alles nicht so geschickt, denn
bei c) blockiert der Thread, es ist also ein "busy waiting". Während des wartens kann sonst niemand was tun.
Bei b) könnten meines Erachtens andere Threads weiterarbeiten. Wenn ich dann immer mit qsocket.bytesAvailable() gucke, ob schon was da ist, verschwenden wir nicht viel Zeit.
Aber: So lange man schläft, wird kein Signal "readyRead()" emmitiert. Nix kommt am Socket an, komischerweise.
Bei a) Lande ich in einem Deadlock. Auch hier kommt nichts mehr am socket an, daher kann man die QWaitCondition nicht mehr lösen.
Zugegeben, die drei Vorschläge erscheinen mir selbst auch noch nicht besonders hübsch, bisher fiel mir aber nichts anderes ein.
Gibt es tolle Ideen/Musterbeispiele/Standardlösungen?
Kommen jemandem die Probleme bekannt vor?
Vielen Dank im Voraus,
Niklas
[/b]