Ich möchte eine performante Gui in Qt schreiben. Und im Hintergrund sollen per Ethernet Nachrichten empfangen werden, die dann in der Gui angezeigt werden. Sollte ich die Empfangsfunktion in einen eigenen Thread auslagern? Bzw. wann sollte man Funktionen in eigene Threads auslagern?
Sollen sollen sollst du gar nichts, und müssen müssen mußt du auch nichts, aber können können könntest du das tun. Das qt aber eigentlich alles für sich erledigt, brauchst du nur auf die passenden Signale zu reagieren. Oliver
Aber wenn ich alle 10 ms eine Nachricht aus dem Ethernet Stack kommt wird die Gui doch möglichen zu langsam!
Otto schrieb: > Aber wenn ich alle 10 ms eine Nachricht aus dem Ethernet Stack kommt > wird die Gui doch möglichen zu langsam! Und was würde der Benutzer für Vorteile daraus ziehen, wenn er alle 10ms neue Informationen gezeigt bekommt? Keine, weil er die Informationen so schnell gar nicht erfassen kann. Also existiert dein Problem nur in deiner Vorstellung, stimmts?
Nein, die Frage des TO ist durchaus berechtigt. Ich habe das gleiche Problem dadurch gelöst, dass ich die (in meinem Fall bis zu 4000 Nachrichten / s) in einem eigenen Thread empfange und dekodiere, sie an die GUI weiterreiche und dort zwischenspeichere. Alle 300ms wird der Speicher (eine QList o. ä.) ausgelesen und die GUI aktualisiert (bis zu 10000 Zeilen). Gruß Olaf
:
Bearbeitet durch User
Olaf Dreyer schrieb: > Thread empfange und dekodiere, sie an die GUI weiterreiche und dort > zwischenspeichere. Alle 300ms wird der Speicher (eine QList o. ä.) > ausgelesen und die GUI aktualisiert (bis zu 10000 Zeilen). Und wie soll der Benutzer 10000 Zeichen / 300 ms lesen können? Was soll das bringen?
Ich schrieb Zeilen, nicht Zeichen. Wenn ich z. B. ein Autoradio teste das per Ethernet seine Traceausgaben schickt, dann kan ich schon bei der Änderung der einzelnen Testparameter erkennen, ob das Gerät vermehrt Fehlermeldungen ausspuckt. Solche werden natürlich an der GUI durch SyntaxHighlighting hervorgerufen. Gruß Olaf
Und zur genaueren Analyse schaut man dann in die Datei, in der die Messages parallel gestreamt wurden. Nochmals Gruß Olaf
Ich meinte natürlich im vorletzten Beitrag: Solche werden natürlich an der GUI durch SyntaxHighlighting hervorgehoben. Gruß Olaf
Meister Eder schrieb: > Und was würde der Benutzer für Vorteile daraus ziehen, wenn er alle 10ms > neue Informationen gezeigt bekommt? Keine, weil er die Informationen so > schnell gar nicht erfassen kann. Also existiert dein Problem nur in > deiner Vorstellung, stimmts? Hallo, du hast recht der Benutzer kann die Inforamtion so schnell nicht erfassen. Aber angenommen ich ersetzt den Ethernet Stack durch einen Can-Stack. Hierbei empfängt mein Anzeigegerät Prozessdaten mit hoher Geschwindigkeit (alle 10 ms). Wie kann ich verhindern, dass mein Gerät nicht ständig damit beschäftigt ist, Nachrichten zu empfangen?
Die GUI kannst bzw. solltest du nicht in einen Thread schieben. Du kannst aber, wie bereits gesagt wurde, zeitaufwändige Aufgaben in einem eigenen Thread machen. Aber wie immer bei Threads ist die Frage, ob das a) tatsächlich schneller ist im Endeffekt und b) den Aufwand lohnt. Mein Rat wäre, es zuerst ohne zu versuchen, und die Thread-Variante nur zu probieren wenn's tatsächlich zu langsam ist. Grüße, Sven
Otto schrieb: > Wie kann ich verhindern, dass mein Gerät > nicht ständig damit beschäftigt ist, Nachrichten zu empfangen? Gar nicht, und da liegt auch dein Denkfehler. Wenn die ganze verfügbare Rechenzeit dafür drauf geht, Daten zu empfangen, dann hilft ein zusätzlicher Thread auch nicht weiter. Mehr verfügbare Rechenzeit bekommst du dadurch nicht. Außer natürlich, bei einem Mehrkernprozessor liegen Kerne brach, die durch einen zusätzlichen Tthread genutzt werden können. Oliver
Das ist Unfug. Die GUI zu verwalten braucht nur sehr wenig Zeit, und selbst wenn die CPU fast komplett mit dem Verarbeiten von irgendwas beschäftigt ist, ist es kein Problem währenddessen noch einen Fortschrittsbalken anzuzeigen oder was auch immer.
Sven B. schrieb: > Das ist Unfug. Die GUI zu verwalten braucht nur sehr wenig Zeit, > und > selbst wenn die CPU fast komplett mit dem Verarbeiten von irgendwas > beschäftigt ist, ist es kein Problem währenddessen noch einen > Fortschrittsbalken anzuzeigen oder was auch immer. Ein Fortschrittsbalken ist kein Problem. Allerdings soll auch navigiert und gescrollt werden können. Und das kostet CPU Leistung.
Kommt halt drauf an, was man genau anzeigen will. Insbesondere halt darauf achten, dass nur so oft gerendert wird wie das auch sinnvoll ist, dass das effizient geschieht, und dass insbesondere nur auf die dazu nötigen Daten zugegriffen wird und nicht auf alle. Es gibt genug Anwendungen, die das ordentlich vormachen, ein typischer Terminal-Emulator zum Beispiel kann problemlos zehntausende Zeilen Text rendern während eine in ihm ausgeführte Anwendung die CPU quasi komplett auslastet.
Was effizienter ist, hängt wirklich von den Details ab, aber wenn ein Datenstrom reinkommt, kann ein Thread der dann auf dem Socket blockiert durchaus die sinnvollste Möglichkeit sein. Man muss da halt überlegen wie man das mit dem Rest des Programmes synchronisiert. Aber, für Fehlermeldungen eines Gerätes braucht man eine GUI Software. So was macht man entweder ganz einfach per TCP-Socket quasi per Telnet, oder per UDP in einem Syslog kompatiblen Format. Dadurch wird die "GUI" zu einem einfachen netcat <DUT-IP> <PORT> > <Dateiname> & tail -f <Dateiname>
Sven B. schrieb: > a) tatsächlich schneller ist im Endeffekt und b) den Aufwand lohnt. Das Problem ist ja weniger die Ausführungsgeschwindiogkeit sondern die Frage ob die GUI noch zügig auf Mausereignisse reagiert während im Hintergrund noch was anderes gemacht wird. Es gibt nichts störenderes als eine GUI die einen Klick nicht augenblicklich entgegennimmt sondern stattdessen wie eingefroren erscheint. Ein separater Thread is weniger Aufwand, nicht mehr. Wenn Du alles im Main-Thread machen willst musst Du aberwitzige Verrrenkungen anstellen um gleichzeitig noch die GUI-Eventloop am laufen zu halten, ein separate Thread jedoch läuft einfach so für sich und kann sich voll auf das konzentrieren wozu er da ist und auch mal 99% seiner Zeit in nem blockierenden read() stecken ohne sich um den Rest der Anwendung irgendwelche Gedanken machen zu müssen. Das ist wesentlich einfacher zu handhaben.
:
Bearbeitet durch User
Es kommt halt immer auf den konkreten Fall an. In dieser Allgemeinheit lässt sich die Fragestellung nicht diskutieren. Klar, wenn du mit einer synchronen API zu tun hast die auch mal länger braucht, führt um einen extra-Thread wohl kein Weg herum.
Ich wuerde den extra thread fuer den externen Prozess verwenden.
Siebzehn Zu Fuenfzehn schrieb: > Ich wuerde den extra thread fuer den externen Prozess verwenden. dito. ohne qt zu kennen finde ich daß das schnelle datenfetchen und die gui nicht "in die selbe loop" gehören. das sind zwei unterscheidliche dinge - die gui soll "in echtzeit" auf nutzereingaben reagieren, und der fetcher soll genügend cpu-cycles haben um seiner aufgabe nachzukommen. wer kennt nicht mindestens ein programm das nicht reagiert weil es beim datenverarbeiten nicht mehr auf den gedrückten abbrechen button reagiert…?
Es kommt halt drauf an. Wenn du eh einen externen Prozess startest und alles was du mit dem tust ist seine Ausgabe in einem Textfeld darzustellen dann bringt dir der extra-Thread genau gar nichts, der macht alles nur schlechter und komplizierter. Der extra-Thread bringt in dem Fall nur was, wenn du sehr rechenaufwendiges Post-Processing mit dem Output von dem Prozess machst.
Sven B. schrieb: > Es kommt halt drauf an. Wenn du eh einen externen Prozess startest Wo steht da daß er nen separaten Prozess startet? Er will Netzwerk-Kommunikation machen und das macht man traditionell mit nem separaten Thread, das ist sauber, übersichtlich, wesentlich einfacher zu handhaben und ist in 3 Minuten hingeschrieben. Dazu braucht man: * die API-Funktion um einen Thread zu starten (1 Zeile Code) * while (!terminated) { * den Code um vom Socket zu lesen (braucht er sowieso) * Empfangenes Paket da hinschreiben wo es der Main Thread abholen kann * Mit Main-Thread synchronisieren (1 Zeile) * }
Bernd K. schrieb: > Sven B. schrieb: >> Es kommt halt drauf an. Wenn du eh einen externen Prozess startest > > Wo steht da daß er nen separaten Prozess startet? Er will > Netzwerk-Kommunikation machen und das macht man traditionell mit nem > separaten Thread, Wusste ich garnicht. Muss da was verpasst haben. > das ist sauber, übersichtlich, wesentlich einfacher zu > handhaben und ist in 3 Minuten hingeschrieben. Ah ja. > Dazu braucht man: > > * die API-Funktion um einen Thread zu starten (1 Zeile Code) > * while (!terminated) { > * den Code um vom Socket zu lesen (braucht er sowieso) > * Empfangenes Paket da hinschreiben wo es der Main Thread abholen kann > * Mit Main-Thread synchronisieren (1 Zeile) > * } Ok, und jetzt erklärst du uns bitte noch etwas über 'volatile' und die Synchronisation. Ich bin mir recht sicher, dass es auf einmal doch mehr als 3 Minuten braucht, wenn man sich bemüht, keine ranzige Müllware zu programmieren. Und schließlich sollte man noch klären, warum überhaupt der Datenempfang so tödlich für die GUI ist. Meistens kommt dabei nämlich heraus, dass der Thread nur eine faule Ausrede dafür ist, dass man keine sauberen Zustandsautomaten programmieren kann/will.
Nase schrieb: > Meistens kommt dabei nämlich > heraus, dass der Thread nur eine faule Ausrede dafür ist, dass man keine > sauberen Zustandsautomaten programmieren kann/will. Was würde denn so ein "sauberer Zustandsautomat" prinzipiell machen ?
Otto schrieb: > Was würde denn so ein "sauberer Zustandsautomat" prinzipiell machen ? Daten empfangen, wenn es welche zu empfangen gibt und verarbeiten, wenn es was zu verarbeiten gibt. Der Zustandsautomat ersetzt damit die lineare Verarbeitung, die man faul in einen Thread reinklatscht. Der Automat dagegen blockiert nicht, sondern muss nur regelmäßig angestoßen (aufgerufen) werden. Wenn man nicht gerade auf einem Mehrkernsystem arbeitet, wird es nämlich durch einen Thread nicht effizienter, weil auch der Thread keine zusätzliche Rechenzeit herbeizaubert. Man muss sich eben Gedanken machen, wie oft man den Automaten anstößt und wie oft (dazwischen) man die Eventloop der GUI anstößt. Und das wird auch mit einem Thread nicht besser. Wenn der Thread gerade in einer atomaren Operation festhängt, dann ist das Scheduling nämlich auch im Eimer und die GUI friert ein. Präemptives Scheduling macht nämlich auch nichts anderes, als den Programmfluss an einer (geeigneten) Stelle abzuwürgen und umzuschalten.
Aber was passiert, wenn ständig Daten verarbeitet werden müssen? -> Der Nachrichtenpuffer muss ausgelesen werden, damit er nicht überläuft. -> Es werden alle 10 ms Nachrichten in den Puffer geschrieben.
Otto schrieb: > Aber was passiert, wenn ständig Daten verarbeitet werden müssen? > -> Der Nachrichtenpuffer muss ausgelesen werden, damit er nicht > überläuft. > -> Es werden alle 10 ms Nachrichten in den Puffer geschrieben. Und was passiert, wenn du das mit Threads machst?
Ich weis das ich dadurch nicht mehr Rechenzeit bekommen. Aber was soll ich sonst machen? Den Puffer auslesen und die Hälfte aller Nachrichten gleich verwerfen?
Otto schrieb: > Ich weis das ich dadurch nicht mehr Rechenzeit bekommen. > Aber was soll ich sonst machen? > Den Puffer auslesen und die Hälfte aller Nachrichten gleich verwerfen? Um die Frage beantworten zu können, mußt du dir nur überlegen, ob das auslesen mehr als 10ms dauert. Wenn nicht, kannst du den Rest der Zeit für die GUI verwenden. Muß ja nicht am Stück sein, die Zeit kann man sich ja mittels Statemachine aufteilen. Wenn das Auslesen aber wirklich länger als 10ms dauern sollte und die Nachrichten kommen aller 10ms rein, dann kannst du, wie du schon gesagt hast, keine Rechenzeit herbeizaubern.
Otto schrieb: > Ich weis das ich dadurch nicht mehr Rechenzeit bekommen. > Aber was soll ich sonst machen? > Den Puffer auslesen und die Hälfte aller Nachrichten gleich verwerfen? Das musst du schon selbst beantworten. Aber du erkennst ja, dass es mit einem Thread nicht besser wird. Eher schlechter wegen der Kontextwechsel. Wenn du mit dem Auswerten nicht hinterherkommst, kannst du die GUI vernachlässigen um dort Rechenzeit zu sparen. Natürlich friert die dann ein. Wenn du dann immer noch nicht hinterherkommst, dann wirst du wohl Nachrichten verwerfen müssen. Wenn die Auswertung aber (zeitlich) teuer ist aber die Zeit der Erfassung nur begrenzt ist, dann könntest du die Nachrichten während der Erfassung unbewertet in einen großen Puffer schreiben und dann anschließend in Ruhe auswerten?
> Muß ja nicht am Stück sein, die Zeit kann man > sich ja mittels Statemachine aufteilen. Wenn das Auslesen aber wirklich > länger als 10ms dauern sollte und die Nachrichten kommen aller 10ms > rein ... > Man muss sich eben Gedanken > machen, wie oft man den Automaten anstößt und wie oft (dazwischen) man > die Eventloop der GUI anstößt. ... Klar, möglichst fummelig, low-level und kaum sinnvoll skalierbar. > Eher schlechter wegen der Kontextwechsel. Das Unterforum hier heißt PC-Programmierung, nicht uC-Programmierung. > dann kannst du, wie du schon gesagt hast, keine Rechenzeit > herbeizaubern. ... > wird es nämlich durch einen Thread nicht effizienter, weil auch der > Thread keine zusätzliche Rechenzeit herbeizaubert. Bevor man Ratschläge gibt, solle man evtl. erst einmal den Unterschied zwischen I/O-bound und CPU-bound kennen ...
Aloha schrieb: > Bevor man Ratschläge gibt, solle man evtl. erst einmal den Unterschied > zwischen I/O-bound und CPU-bound kennen ... Hast du außer Genörgel auch noch etwas beizutragen, was den OT irgendwie weiterbringt? Ansonsten solltest du vielleicht zuerst das ganze Thema lesen. Aber gottseidank - ja GOTTSEIDANK - skalieren Threads genau bei diesem Problem hier so ausgezeichnet gut. Geh doch bitte wieder Java-Bloat spielen.
Aloha schrieb: > Klar, möglichst fummelig, low-level und kaum sinnvoll skalierbar. Was ist bitte an einer Statemachine "fummelig, low-level und kaum sinnvoll skalierbar"? Das weißt bestimmt nur du allein. ;-)
Das ist nicht fummelig. In Qt benutzt du zum Beispiel QTcpSocket und verbindest dich mit dem readyRead()-Signal. Das in einem Thread zu machen bringt so gut wie nichts, außer du willst halt wie gesagt rechenaufwändiges Post-Processing machen.
Sven B. schrieb: > Das ist nicht fummelig. In Qt benutzt du zum Beispiel QTcpSocket und > verbindest dich mit dem readyRead()-Signal. Zum Beispiel, genau. Und was hast du dann? Richtig: Einen Zustandsautomaten. Denn nichts anderes ist das QT-Eventzeugs nämlich. > Das in einem Thread zu > machen bringt so gut wie nichts, außer du willst halt wie gesagt > rechenaufwändiges Post-Processing machen. Und selbst da bringt der Thread nichts, wenn keine Rechenzeit mehr da ist oder wenn der Scheduler die beiden Threads auf dieselbe CPU packt. Außer, dass man sich noch um die Synchronisierung kümmern muss. Ok, QT-Signale gehen auch threadsicher, aber einfacher wirds auch nicht.
Nase schrieb: > Sven B. schrieb: >> Das ist nicht fummelig. In Qt benutzt du zum Beispiel QTcpSocket und >> verbindest dich mit dem readyRead()-Signal. > Zum Beispiel, genau. > Und was hast du dann? Richtig: Einen Zustandsautomaten. Denn nichts > anderes ist das QT-Eventzeugs nämlich. Jo, klar, hat auch niemand was gegenteiliges behauptet :-)
Nase schrieb: > Wenn man nicht gerade auf einem Mehrkernsystem arbeitet, wird es nämlich > durch einen Thread nicht effizienter Nochmal zum Mitschreiben: Es geht nicht darum ob es effizienter wird denn nichts davon ist CPU-bound sondern es geht darum daß es mit einem separaten Thread simpler, aufgeräumter, unkomplizierter, weniger Code und einfacher wartbar wird. Separation of concerns. Das GUI hat nicht im Netzwerk herumzufuhrwerken, es hat 100% seiner Zeit auf die Maus und die Tastatur zu warten und ab und zu mal Teile der Fenster neu zu malen und sonst nichts. Ach und das hat übrigens auch nichts mit "volatile" zu tun und Synchronize() ist bei mir eine Zeile Code (und eine Handler-Funktion auf der anderen Seite) und wenns Asynchron laufen soll dann gibts dafür ebenfalls simple Mechanismen, jedes Framework das ich bis jetzt gesehen habe bringt solche Mechanismen schon mit und das Framework das OP verwendet mit Sicherheit ebenfalls.
Bernd K. schrieb: > sondern es geht darum daß es mit einem > separaten Thread simpler, aufgeräumter, unkomplizierter, weniger Code > und einfacher wartbar wird. Das ist meiner Meinung nach definitiv falsch. Wahrscheinlich 80% aller Bugs haben irgendwas mit Threads zu tun, und die vermeidet man am einfachsten, indem man keine Threads hat wenn es irgendwie geht. Mit aufgeräumtem Code hat das überhaupt nichts zu tun (warum sollte es?).
:
Bearbeitet durch User
Sven B. schrieb: > 80% aller > Bugs haben irgendwas mit Threads zu tun, Nachweis? > und die vermeidet man am > einfachsten, indem man keine Threads hat wenn es irgendwie geht. Ich weiß nicht welche Probleme manche Leute mit Threads haben, es gibt ein paar Sachen die man beachten muß, aber das muß man bei tausend anderen Designpatterns ebenfalls, Threads per se sind auch nicht irgendwie inherent komplizierter als alles andere. Und sie helfen oftmals verschiedene Abläufe die vollkommen unabhängig voneinander (auch und vor allem zeitlich) ablaufen sollen sauber voneinander zu entkoppeln. Im Wesentlichen muss man lediglich an der einen kleinen Stelle aufpassen an der zwei Threads miteinander Informationen austauschen und dafür gibts klare und bewährte Vorgehensweisen. In dem Beispiel mit einem GUI-Thread und einem Netwerk-Thread wäre das absolut trivial.
Bernd K. schrieb: > Nachweis? In der Anwendung in der ich da ein bisschen den Überblick habe durch was Crashes verursacht werden ist das so. > In dem > Beispiel mit einem GUI-Thread und einem Netwerk-Thread wäre das absolut > trivial. Threads sind viele Dinge, aber nach meiner Erfahrung nie trivial. Vielleicht bin ich auch einfach nur doof, aber ich finde den ganzen Thread-Kram im Detail sehr kompliziert und sehr leicht falsch zu machen.
Sven B. schrieb: > Threads sind viele Dinge, aber nach meiner Erfahrung nie trivial. > Vielleicht bin ich auch einfach nur doof, aber ich finde den ganzen > Thread-Kram im Detail sehr kompliziert und sehr leicht falsch zu machen. Dann benutzt du die falsche Programmiersprache ;-))
Bernd K. schrieb: > Nase schrieb: >> Wenn man nicht gerade auf einem Mehrkernsystem arbeitet, wird es nämlich >> durch einen Thread nicht effizienter > > Nochmal zum Mitschreiben: Es geht nicht darum ob es effizienter wird > denn nichts davon ist CPU-bound sondern es geht darum daß es mit einem > separaten Thread simpler, aufgeräumter, unkomplizierter, weniger Code > und einfacher wartbar wird. Die meisten Programme scheitern ja schon daran, sauber aus einem blockierten Aufruf heraus abzubrechen. 'Separation of concerns' geht wunderbar ohne Threads. Es geht auch wunderbar mit Threads. Aber so wie der OT sein Problem bislang umrissen hat, würde ich mich in diesem Fall nicht freiwillig Threads antun. Vorallem 'synchronize' in Java ist immer wieder lustig. Selbst in der Doku hat man das schon erkannt ('be very careful') ...
Nase schrieb: > würde ich mich in diesem Fall nicht freiwillig Threads antun. Wieso antun? Ich empfinde Threads als eine nützliche Erweiterung meiner Werkzeugkiste die ich gerne anwende wenn es sich anbietet (so wie im vorliegenden Falle). Schließlich stellen Threads ja keinen Mehraufwand dar (im Gegenteil) und übersichtlicher und modularer wirds dadurch auch ;-)
:
Bearbeitet durch User
Bernd K. schrieb: > Wieso antun? Ich empfinde Threads als eine nützliche Erweiterung meiner > Werkzeugkiste die ich gerne anwende wenn es sich anbietet (so wie im > vorliegenden Falle). Schließlich stellen Threads ja keinen Mehraufwand > dar (im Gegenteil) und übersichtlicher und modularer wirds dadurch auch > ;-) Und genau diese Vorgehensweise halte ich für nicht zielführend. Threads sind nichts was man einfach mal so über eine Anwendung drüberstreut, weil man das halt kann, sondern man sollte die nur einsetzen, wenn man einen sehr guten Grund dafür hat. Und "meine Anwendung wird dadurch modularer" ist definitiv kein Grund. Das kannst du ganz genau so auch ohne Threads machen.
man könnte auch einfach nicht jedes mal das Rad neu erfinden, und eine Biliothek verwenden die das schon mit threads macht..(was wohl eh alle machen) (sowas wirds ja wohl auch für Qt geben?)
was?
na genau das was der TO will
>Und im Hintergrund sollen per Ethernet Nachrichten empfangen werden,
Mir ist nicht klar wozu man dazu einen Thread braucht. Der Kernel füllt doch so einen Buffer und schickt dir ein Event wenn der voll ist, oder?
Hab nur bis zur Hälfte mitgelesen, aber ich hol mir jetzt erstmal Popcorn. Die Diskussionen sind ja filmreif! :) Bitte weiter so.
Sven B. schrieb: > Der Kernel füllt > doch so einen Buffer und schickt dir ein Event wenn der voll ist, oder? Nein.
Bernd K. schrieb: > Sven B. schrieb: >> Der Kernel füllt >> doch so einen Buffer und schickt dir ein Event wenn der voll ist, oder? > > Nein. Sondern?
Sven B. schrieb: > Bernd K. schrieb: >> Sven B. schrieb: >>> Der Kernel füllt >>> doch so einen Buffer und schickt dir ein Event wenn der voll ist, oder? >> >> Nein. > > Sondern? Du wartest auf das Event.
Bernd K. schrieb: >>> Nein. >> >> Sondern? > > Du wartest auf das Event. Ich warte nicht aktiv auf das Event. Das steht in irgendeiner Warteschlange und ich arbeite es ab wenn ich Lust dazu habe.
Sven B. schrieb: > Bernd K. schrieb: >>>> Nein. >>> >>> Sondern? >> >> Du wartest auf das Event. > > Ich warte nicht aktiv auf das Event. Das steht in irgendeiner > Warteschlange und ich arbeite es ab wenn ich Lust dazu habe. Scroll mal nach oben: Es geht um "performant". Das ist inkompatibel mit "wenn ich Lust dazu habe". Und wenn Du eh nur pollen willst wenn Du gerade mal wieder ein bisschen Lust hast dann brauchst Du auch kein Event.
Es geht um "performant" im Sinne von "weniger als 20ms Reaktionszeit". Da ist es völlig ok, wenn das Event abgearbeitet wird, wenn die Event Loop das nächste mal ausgeführt wird.
Sven B. schrieb: > Es geht um "performant" im Sinne von "weniger als 20ms Reaktionszeit". > Da ist es völlig ok, wenn das Event abgearbeitet wird, wenn die Event > Loop das nächste mal ausgeführt wird. Ach, machs doch so Du willst. OP hat sich wahrscheinlich eh schon längst verabschieded und ich bin (und bleibe) ein Befürworter von modularem Design und loser Kopplung und alles was autonom funktionieren kann soll auch autonom funktionieren und schön gekapselt und austauschbar sein und wenn das Ding zur Erfüllung seiner internen Aufgaben auf Events warten muss dann bekommt es eben mal intern seinen eigenen Thread, warum denn auch nicht? Man könnte fast meinen manchen Leuten wurde irgendwann in den letzten 4 Jahren eingetrichtert daß Nebenläufigkeit generell vom Teufel erfunden wurde. Ist das etwa die JavaScript-Fraktion, jene Leute die spätestens seit node überall nur noch Nägel für ihren (einen) Hammer sehen, die erfolgreich für sich den Mangel zum Feature umdefiniert haben? Mann mann mann, allein in der Zeit die dieser unselige Thread hier jetzt schon diskutiert wird hätte man einen ganzen Threadpool schreiben können.
Bernd K. schrieb: > OP hat sich wahrscheinlich eh schon längst verabschieded und ich bin > (und bleibe) ein Befürworter von modularem Design und loser Kopplung und > alles was autonom funktionieren kann soll auch autonom funktionieren und > schön gekapselt und austauschbar sein und wenn das Ding zur Erfüllung > seiner internen Aufgaben auf Events warten muss ... was, zum n-ten mal, überhaupt nichts mit Threads zu tun hat. Nichts. Außer vielleicht dem letzten Teil mit den Events wenn die Events irgendwie synchron ankommen. Was aber zum Beispiel bei Input-Events nicht der Fall ist. > dann bekommt es eben mal > intern seinen eigenen Thread, warum denn auch nicht? "intern"? Den sehe ich sogar in meinem Task-Manager, wenn ich deine Anwendung ausführe. Und warum nicht? Weil es im Zweifelsfall leicht mal schlechtere Performance mit sich bringt (Kontextwechsel!) und die Komplexität der Anwendung erhöht, wenn man einfach nur so ein paar Threads über die Anwendung streut "weil man es kann".
:
Bearbeitet durch User
Sven B. schrieb: > und die > Komplexität der Anwendung erhöht, Zum n-ten Mal: nein. Siehe oben. Pollen ist inakzeptabel und unperformant, da sind sich ja wohl alle einig. Was schlägst Du also vor? Lass Dir Zeit mit der Antwort, ich hau mich jetzt aufs Ohr.
:
Bearbeitet durch User
Bernd K. schrieb: > Pollen ist inakzeptabel und > unperformant, da sind sich ja wohl alle einig. Nein, genau da ist sich keiner hier einig. Einzig du allein hast Pollen grundlos als inakzeptabel hingestellt.
Nase schrieb: > Nein, genau da ist sich keiner hier einig. Hier vielleicht nicht, in Fachkreisen jedoch schon. Und deshalb klinke ich mich an dieser Stelle mal hier aus, das führt eh zu nichts.
Um mal auf das Thema zurückzukommen: Immerhin geht es hier ja um Qt. Zum Thema "Performantes GUI" gibt's da ja nun schon einiges an Doku, und auch zum Thema Threads. Der TO muß da also einfach nur mal nachlesen. So als Einstieg: http://qt-project.org/doc/qt-5/thread-basics.html#when-to-use-alternatives-to-threads Oliver
Bernd K. schrieb: > Nase schrieb: >> Nein, genau da ist sich keiner hier einig. > > Hier vielleicht nicht, in Fachkreisen jedoch schon. Und deshalb klinke > ich mich an dieser Stelle mal hier aus, das führt eh zu nichts. Oooh, in "Fachkreisen", soso! Mit Polling hat das doch alles nix zu tun. Der Unterschied ob man das Event-Handling im GUI-Thread macht oder nicht ist einfach nur der: im ersten Fall kommt das Event (z.B. "neuer Kram aus dem Netzwerk angekommen") in der Event-Loop vom GUI-Thread an; im zweiten Fall hast du einen zweiten Thread, der selber eine Event Loop hat, und das Event kommt dort an, und der Kernel wechselt zwischen den beiden Loops hin und her. Das ist in dem Fall absolut kontraproduktiv.
Sven B. schrieb: > Das ist in dem Fall absolut kontraproduktiv. Nein. Es ist kontraproduktiv irgendwelche internen Low-level Routinen im Backend vom Frontend abhängig zu machen. Sowas trennt man sauber wenns nicht gerade das absolut simpleste mal eben hingehackte Wegwerf-Programm ist. Was machst Du wenn Du diese Protokollimplementierung morgen in ner Konsolenanwendung brauchst? Oder für Linux mit GTK anstelle von Irgendwas/Qt? Oder Windows? Oder als native Library fürn Android-Handy? Willst Du dann das innerste nach außen stülpen nur damit die jeweilige GUI direkt an den Sockets herumfuhrwerken um die Arbeit zu verrichten die das Ding eigentlich ungefragt und klaglos eigenständig tun sollte? Das will kein Mensch (oder ich zumindest jedenfalls nicht, wenn Du das willst ist das Dein Problem). OP hat gefragt ob er einen separaten Thread nehmen soll für die Dinge die das GUI nichts anzugehen haben. Die Antwort ist ein klares Ja.
Bernd K. schrieb: > Sven B. schrieb: >> Das ist in dem Fall absolut kontraproduktiv. > > Nein. Es ist kontraproduktiv irgendwelche internen Low-level Routinen im > Backend vom Frontend abhängig zu machen. Von welchen Low-Level-Routinen sprichst du? Qt Event Loop? Du kannst keine Anwendung mit Qt schreiben ohne die Event Loop mit einzubeziehen. Wenn deine Idee von Encapsulation ist, Netzwerkzugriff in einer Qt-Anwendung zu machen, indem man vermeidet die Event Loop zu benutzen, dann weiß ich auch nicht mehr was ich sagen soll. > Sowas trennt man sauber wenns > nicht gerade das absolut simpleste mal eben hingehackte Wegwerf-Programm > ist. Ja, klar, kein Widerspruch hier. Außer du meinst, dass man die Implementierung vom Netzwerk-Code vom Framework trennt das man für den Netzwerkzugriff verwendet, was vollkommen absurd wäre. > Was machst Du wenn Du diese Protokollimplementierung morgen in ner > Konsolenanwendung brauchst? Wie gesagt, kein Widerspruch hier. Hat aber nix mit Threads zu tun. > Oder für Linux mit GTK anstelle von > Irgendwas/Qt? Pech. Ungefähr genauso Pech wie wenn ich mir morgen überlege dass ich meine Anwendung jetzt in Haskell schreiben will und mein Netzwerk-Code aber schon in C ist. Du darfst hier gerne anderer Meinung sein, aber ich persönlich werde niemals Code in einer Anwendung schreiben mit dem Hintergedanken "wenn ich mal das Framework wechsle, was in jeder Zeile meiner Anwendung verbaut habe, möchte ich diesen Code immer noch verwenden können". Das ist in meiner Welt einfach grober Unfug. > Oder Windows? Oder als native Library fürn Android-Handy? Qt unterstützt beide Plattformen. > OP hat gefragt ob er einen separaten Thread nehmen soll für die Dinge > die das GUI nichts anzugehen haben. Die Antwort ist ein klares Ja. Die Antwort ist ein klares Nein, außer die Aufgaben sind rechenzeitintensiv (und zwar im Sinne von "Rohdaten verarbeiten", nicht "Rohdaten in ein Textfeld malen", dafür bringt der Thread nämlich nichts) oder müssen von einer synchronen API geholt werden.
Sven B. schrieb: > Außer du meinst, dass man die > Implementierung vom Netzwerk-Code vom Framework trennt das man für den > Netzwerkzugriff verwendet Nein. Ich meine daß man den Code für ein Netzwerkprotokoll nicht mit einem GUI-Framework implementiert. Schon gar nicht mit so einem Zweistelligen Multi-Magabyte-Monster wie Qt. Nicht jedes Problem ist ein Nagel.
Qt ist nicht nur ein GUI-Framework. QtNetwork hängt nur von QtCore ab, du kannst also QtNetwork verwenden ohne auch nur eine Zeile GUI-Code in deiner Anwendung zu haben. Nicht QtNetwork zu verwenden wenn ich eh Qt benutze halte ich für Schwachsinn, aber wenn dir das aufgrund irgendwelcher theoretischen Argumente die in der Praxis keinerlei Relevanz haben Spaß macht, ok. Die GUI-Teile sind so Dinge wie QtWidgets, aber viele Komponenten von Qt haben mit GUI nix zu tun.
:
Bearbeitet durch User
Du predigst einerseits andauernd Sparsamkeit mit Einwänden über irgendwelche ominösen Kontextwechsel (weil Du das Wort mal irgendwo in nem anderen Zusammenhang aufgeschnappt hast) die bei der hier betrachteten Aufgabenstellkung überhaupt nicht relevant sind (weil nichts davon ist CPU-bound, alle beide Threads schlafen fast **immer**) und andererseits willst Du selbst simpleste 10-Zeiler mit ein bisschen leichtgewichtigem Socket-IO von Monster-Libraries wie Qt abhängig machen. Ich gebs auf. EOD.
:
Bearbeitet durch User
Du hast eh eine Qt-Anwendung laufen. Jetzt hast du die Wahl ob du einfach QtNetwork nimmst, was sich da schön einfügt, oder irgendeine andere Netzwerk-Bibliothek (was für deine Anwendung übrigens erstmal eine zusätzliche Abhängigkeit bedeutet!) und deren Event Loop (die haben nämlich üblicherweise alle eine) irgendwie mit der Qt Loop zusammenfrickelst (was überhaupt keinen Spaß macht, glaub mir). Ich verstehe nicht, was an der Entscheidung schwer ist.
Sven B. schrieb: > oder irgendeine > andere Netzwerk-Bibliothek Man braucht überhaupt keine "Netzwerk-Bibliothek" um einen socket zu öffnen, zu lesen, zu schreiben oder select() zu verwenden. Das Zeug ist alles in der libc schon drin. und in der Windows-API isses auch drin. Gute Nacht.
Ach so, die Windows-API. Das ist natürlich harte Konkurenz in Sachen Entkopplung von unnötigen Dependencies.
Sven B. schrieb: > Ach so, die Windows-API. Das ist natürlich harte Konkurenz in Sachen > Entkopplung von unnötigen Dependencies. Nicht bei Sockets. Wie ich schrieb sind sowohl sockets als auch send(), recv() und select() auch in der libc und nahezu identisch in der Windows API. Da reicht ein einziges ifdef und weniger als eine Bildschirmseite Code um alle ein für allemal zu erschlagen.
in Zeiten von, kaufe ich mir 8 oder 16 CPU Kernen: Also ICH nehme lieber eine MEGA-ÜBER-DRÜBER Library (z.b. Indy10) das Problem ist nämlich: wenn morgen "jemand" (z.B. Chef) mit dem Falsch Fuß aufsteht, und sagt: hey, wir machen das ab jetzt mit SSL ! dann kann ich sage: jo chef, mach ma mal 2 Zeilen code mehr und des rennt.. ;-) GUI in Windows funktioniert NUR mit Pollen (egal wie gern man das hat..) in einen thread "auslagern" wird man also wohl am ehesten die Bearbeitung der empfangenen Daten ... (damit dem Main-Thread immer schön langweilig ist..) (interessant wird das ganz eh erste wenn man einen Server hat, und keinen Client.. um sich dann zu überlegen wie viele Threads mach ich bei wievielen Verbindungen...)
Bernd K. schrieb: > Sven B. schrieb: >> Ach so, die Windows-API. Das ist natürlich harte Konkurenz in Sachen >> Entkopplung von unnötigen Dependencies. > > Nicht bei Sockets. Wie ich schrieb sind sowohl sockets als auch send(), > recv() und select() auch in der libc und nahezu identisch in der Windows > API. Da reicht ein einziges ifdef und weniger als eine Bildschirmseite > Code um alle ein für allemal zu erschlagen. Naja, ich weiß auch nicht warum's jetzt plötzlich darum geht, warum die Windows-API so viel toller ist um in einer Qt-Anwendung Netzwerk zu implementieren als QtNetwork. Mit dem eigentlichen Thema hat das alles nichts zu tun. Interessiert mich auch eher tangential, ich halte es für groben Unfug, aber wenn du willst, bitteschön. Ich benutze doch nicht Qt in meiner Anwendung und mache dann Netzwerk mit der Windows-API, weil ich da ja "nur ein #ifdef" brauche damit es nicht komplett kacke sondern nur ziemlich kacke ist. Wenn Netzwerk so einfach wäre, dass man da nur "eine Bildschirmseite Code" braucht, gäb's dafür keine Bibliotheken wie QtNetwork und Twisted. Es ist halt nicht so einfach, siehe etwa das Beispiel mit SSL -- oder nimm an, du willst HTTP machen oder sowas, auch nicht so einfach. Außerdem musst du dir in dem Fall deine Event Loop selber schreiben und wenn du dann z.B. einen Qt Slot in deinem Thread willst, wird das wieder anstrengend.
:
Bearbeitet durch User
Bernd K. schrieb: > Man braucht überhaupt keine "Netzwerk-Bibliothek" um einen socket zu > öffnen, zu lesen, zu schreiben oder select() zu verwenden. Das Zeug ist > alles in der libc schon drin. und in der Windows-API isses auch drin. Ach, und ich dachte, gerade DU wolltest keine low-level-Frickelei. Und du predigst doch auch dauernd, dass das alles nicht CPU-bound ist. Das spricht ja noch viel mehr dafür, es in einem Thread zu tun, weil der ja ohnehin fast nichts zu tun hat. Modularisieren geht damit auch prima. Sogar noch einfacher, als wenn man Threads kreuz und quer miteinander synchronisieren muss.
Nase schrieb: > als wenn man > Threads kreuz und quer miteinander synchronisieren muss. Im vorliegenden Falle muss man gar nichts "kreuz und quer" synchronisieren. Bist Du als kleines Kind mal von nem Thread gebissen worden? Oder wie sonst kommt diese irrationale Abneigung gegen ein x beliebiges Allerweltspattern zustande mit dem niemand sonst auf der Welt Probleme zu haben scheint? Gibts etwa noch andere grundlegende Paradigmen oder Sprachelemente vor denen Du so eine irrationale Angst hast? Erzähl mal!
Bernd K. schrieb: > Oder wie > sonst kommt diese irrationale Abneigung gegen ein x beliebiges > Allerweltspattern zustande mit dem niemand sonst auf der Welt Probleme > zu haben scheint? Ich hab' mit deiner Vorgehensweise zu dem Pattern auch Probleme, damit sind wir immerhin schon zwei. Das ist genau wie mit diesen Design Patterns, die wendet man nur an wenn man einen wirklich guten Grund dafür hat, und nicht einfach so weil man es kann.
Sven B. schrieb: > Das ist genau wie mit diesen Design > Patterns, die wendet man nur an wenn man einen wirklich guten Grund > dafür hat, und nicht einfach so weil man es kann. Als Grund sollte genügen: "ich möchte eine Software schreiben". Wenn man eine Softwarearchitektur entwirft, sollten geeignete Design patterns stets die Grundlage sein.
Boris P. schrieb: > sollten geeignete Design > patterns Ja, geeignete. Zu 'geeignet' gehört m.M.n. zum Beispiel auch, das jeweils einfachst-mögliche Pattern zu implementieren. Das selbst ist wieder ein Pattern, nämlich KISS. Threads sind in diesem Fall ganz sicher nicht das einfachst-mögliche. Bernd K. schrieb: > Bist Du als kleines Kind mal von nem Thread gebissen worden? Nö, ich für meinen Teil habe Threads verinnerlicht. > Oder wie > sonst kommt diese irrationale Abneigung gegen ein x beliebiges > Allerweltspattern zustande mit dem niemand sonst auf der Welt Probleme > zu haben scheint? Gibts etwa noch andere grundlegende Paradigmen oder > Sprachelemente vor denen Du so eine irrationale Angst hast? Erzähl mal! Ich habe keine Angst vor Sprachelementen im Allgemeinen. Nur gegen unbedachtes Einsetzen derselben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.