Wieso lassen so viele Programme den Benutzer so lange warten?
-
Hi,
heute frage ich mich also, wieso so viele Programme ständig bei zwischenzeitlichen Rechnungen den Benutzer warten lassen. Beispielsweise Chrome, wenn ich diverse Java-Applets starte. Aber dabei bleibt es nicht, auch diverse Programme, die Zugriffe auf Datenbanken starten oder diverse Programme, die blockieren, wenn sie Verbindung zum Internet aufnehmen.
Man kann doch einfach alles, was irgendwie blockieren oder dauern kann, in Threads auslagern und schon sollte der Benutzer nicht mehr durch das Einfrieren genervt werden. Es ist sicherlich etwas mehr Aufwand, aber würde für mich den Komfort sehr häufig erhöhen.
Warum wird das so nicht gemacht? Oder kann ein sehr belasteter Thread sogar den Hauptthread mitblockieren und ist das dann wohl meist der Fall?
PS: Das Wort "divers" wurde an diversen Stellen verwendet.
-
Eisflamme schrieb:
Warum wird das so nicht gemacht? Oder kann ein sehr belasteter Thread sogar den Hauptthread mitblockieren und ist das dann wohl meist der Fall?
Nur bei enorm hoher Threadpriorität kann das ganze System einfrieren.
Ansonsten kann man nicht "einfach mal so" alles in Threads auslagern. Beschäftige dich mit dem Thema, dann siehst Du wie komplex es ist.
-
Ich schaue mir das alles ja gerade an. Das Hauptproblem liegt wohl in gemeinsam genutzten Resourcen, aber wenn es einfach nur um einen "Fetch" (aus DB, aus Internet usw.) geht, dann sehe ich nicht, was das Problem ist, wenn man sicherstellt, dass während des Fetchs eben die bisher gesammelten Ressourcen nicht genutzt werden können.
Und bei Chrome verstehe ich das auch nicht. Ein Java-Applet kann doch ohne weiteres als zusätzlicher Thread/Prozess ausgeführt werden. Jetzt bricht dieses Applet aus mir unbekannten Gründen zusammen und schon ist ganz Chrome kaputt. Das lässt sich doch gut vermeiden?
Würde mich über konkretere Hinweise, wo das Problem liegt, freuen.
-
Wenn jeder etwas länger andauernde Arbeitsauftrag asynchron ausgeführt wird, muss man als Programmierer stets sicherstellen, dass der Benutzer durch weiteres rumgeclicke keinen Unsinn anstellen kann. Das heißt im einfachsten Fall Steuerelemente ausblenden.
Weiters muss jeder Thread auch wieder kontrolliert abgebrochen werden können. Das ist oft nicht trivial.Es ist gelegentlich ein Segen, den scheiß Benutzer einfach etwas warten zu lassen. Die meisten sind sowieso zu dumm um zu wissen, dass es besser gehen könnte.
-
Also wird das nicht gemacht, weil man den Aufwand nicht als angemessen ggü. dem Nutzen sieht? Ich finde, solche Dinge schränken die Benutzerfreundlichkeit oft erheblich ein. Selbst ein Dialog mit einem Ladebalken und Abbruch bei Bedarf würde schon reichen. Dann ist das Hauptfenster sowieso eingefroren und man braucht bloß blockieren, dass der Benutzer den Dialog anderweitig schließen kann.
-
Wieso steigen die Menschen nicht endlich auf erneuerbare Energien um?
Wenn der Wille da wär, könnte man das doch einfach machen?
-
Eisflamme schrieb:
Also wird das nicht gemacht, weil man den Aufwand nicht als angemessen ggü. dem Nutzen sieht?
Zeit ist Geld.
Wenn ich zum Spaß programmiere, lege ich wert auf Qualität. Wenn ich meine Brötchen damit verdiene, höre ich exakt dann auf sobald der Dummkunde nicht mehr meckert.
-
Eisflamme schrieb:
Selbst ein Dialog mit einem Ladebalken und Abbruch bei Bedarf würde schon reichen.
Das ist schon einiges an Arbeit. Willst du das für jede Winzfunktion machen von der du vielleicht gar nicht erwartest das sie länger braucht? (dazu kann schon jeder Dateizugriff zählen; könnte ja auf einem Netzlaufwerk liegen oder einer externen Festplatte die erst anlaufen muss oder eine durch massives paging überlastete Festplatte)
-
In WinRT ist es ja so, das Async-Programmierung zur Pflicht wird. MS sagt ja, das Funktionen, die poteziell länger als 0,5 sec (oder wie der Wert genau war) asynchron ausgeführt werden muß.
MS sagt aber auch, das die wenigsten Programmierer damit Erfahrung haben.
Meine Meinung: bisher war Thread- bzw. Async-Programmierung auch nicht so von Vorteil. Warum? Weil bis vor kurzem die Computer nur einen gleichzeitig Thread ausführen konnten. Und auch die Thread-Erzeugung nicht gerade super schnell ist, hat man am Ende vielleicht nichts gewonnen, außer mehr Resourcen-Verbrauch.
Heute mit Dual-Cores sieht die Sache schon etwas besser aus. Auch wenn die Thread-Erzeugung immer noch so langsam geblieben ist, können längere Threads davon profitieren.
Um der langsamen Thread-Erzeugung entgegen zu treten, muß man auch einen Thread-Pool nutzen. Wer erzeugt diesen? Gibt es Libraries dafür?
Und was passiert, wenn eine Funktion im Worker-Thread abgearbeitet wird: kann die GUI weiter bedient werden? Blende ich eine Sanduhr ein?
Weiterhin ist die Frage, ob es für die Programmierer gute Unterstützung von der Sprache und Library gab? Ich habe die Erfahrung gemacht, das dem nicht so ist.
C++11 und WinRT wird man offensiv unterstützt async programmieren zu können.
-
Eisflamme! Bitte ändere die Begrifflichkeit "einfrieren"! Einfrieren heißt eigentlich, das das Programm nicht weiter läuft. Ich musste dein Posting zweimal lesen, um zu verstehen was du meinst.
-
Artchi schrieb:
Auch wenn die Thread-Erzeugung immer noch so langsam geblieben ist, können längere Threads davon profitieren.
Na wenn das erzeugen zu langsam ist verwendet man ihn einfach mehrfach.
-
Artchi schrieb:
MS sagt ja, das Funktionen, die poteziell länger als 0,5 sec (oder wie der Wert genau war) asynchron ausgeführt werden muß.
Wie genau wollen die das erzwingen?
-
Weil bis vor kurzem die Computer nur einen gleichzeitig Thread ausführen konnten.
Du lebtest bis vor kurzem in der Steinzeit.
Um der langsamen Thread-Erzeugung entgegen zu treten, muß man auch einen Thread-Pool nutzen. Wer erzeugt diesen? Gibt es Libraries dafür?
Nur sterben muss man. Und ja, es gibt schon lange Bibliotheken dafuer.
Ich habe die Erfahrung gemacht, das dem nicht so ist.
Dann sammle mehr Erfahrungen.
Ansonsten scheinst du mir ein MS-Fanboy zu sein. Der Tellerrand wartet auf dich: Java, Lisp, Haskell.
-
Sorry, hab den OP geändert. Chrome friert bei mir in letzter Zeit tatsächlich ein, aber darauf wollte ich nicht hinaus.
Wie lange dauert Threaderzeugung denn, dass das ins Gewicht fällt? Mehr als eine Sekunde? Falls nicht, würde sich das nämlich für die Fälle, die ich meine, schon lohnen. Es geht auch nicht um Berechnungen, die eine halbe Sekunde dauern, sondern über 10 Sekunden o.ä. Datenbankabfrage sind ja schon Mal so eine Sache. Wenn man in einem Programm arbeitet und eine Abfrage macht, die länger dauert als der Benutzer erwartet, wäre es doch nett, wenn er das abbrechen könnte oder an eine andere Stelle im Programm geht, je nachdem, ob man da noch was anderes nutzen kann.
Ich habe ja mittlerweile Mal etwas in Multithreading reingeschnuppert und weiß, dass es ein gewisser Aufwand ist, auch weil die Entwicklung damit ein Gebiet ist, die sich von Programmierung mit einem Thread massiv unterscheidet. Nur na ja... ich denke, wenn es am Aufwand oder an den Programmiern liegt, dann ist das etwas, was man auf Dauer angehen sollte... sei es durch mehr Bibliotheken oder Tutorials oder eben so eine Einbindung in WinRT... aber das sind doch keine dauerhaften Probleme..?
-
Eisflamme schrieb:
Wie lange dauert Threaderzeugung denn, dass das ins Gewicht fällt? Mehr als eine Sekunde?
Himmel, nein. Das geht viel schneller. Außerdem gibt es die bereits erwähnten Threadpools.
Ich habe mir vor längerem mal ein paar Zeiten zum Thema Threading aus verschiedenen Büchern/Quellen rausgeschrieben. Das bezieht sich auf C# und einen aktuellen Desktop-PC, kann aber allgemein einen Eindruck vermitteln.
Thread time-slice: tens-of-milliseconds Thread start: few hundred microseconds Switch Thread-Context: few-microseconds lock (aquire & release): 20 nanoseconds (bei Context-Switch entsprechend länger) Mutex: few microseconds -> 50 times slower than a lock Semaphore (WaitOne & Release): 1 microsecond AutoResetEvent & ManualResetEvent: 1 microsecond for wait and signal (with no blocking) [Synchronization] & ContextBoundObject: 1 microsend per (wrapped) method call Monitor. Pulse: 100 nanoseconds. Wait: ~ cost of lock
-
Eisflamme schrieb:
Sorry, hab den OP geändert. Chrome friert bei mir in letzter Zeit tatsächlich ein, aber darauf wollte ich nicht hinaus.
Wie lange dauert Threaderzeugung denn, dass das ins Gewicht fällt? Mehr als eine Sekunde? Falls nicht, würde sich das nämlich für die Fälle, die ich meine, schon lohnen. Es geht auch nicht um Berechnungen, die eine halbe Sekunde dauern, sondern über 10 Sekunden o.ä. Datenbankabfrage sind ja schon Mal so eine Sache. Wenn man in einem Programm arbeitet und eine Abfrage macht, die länger dauert als der Benutzer erwartet, wäre es doch nett, wenn er das abbrechen könnte oder an eine andere Stelle im Programm geht, je nachdem, ob man da noch was anderes nutzen kann.
Ich habe ja mittlerweile Mal etwas in Multithreading reingeschnuppert und weiß, dass es ein gewisser Aufwand ist, auch weil die Entwicklung damit ein Gebiet ist, die sich von Programmierung mit einem Thread massiv unterscheidet. Nur na ja... ich denke, wenn es am Aufwand oder an den Programmiern liegt, dann ist das etwas, was man auf Dauer angehen sollte... sei es durch mehr Bibliotheken oder Tutorials oder eben so eine Einbindung in WinRT... aber das sind doch keine dauerhaften Probleme..?
Es ist nicht nur "etwas Aufwand" sondern sehr viel. Außerdem ist es hoch riskant.Damit kann man sich Fehler einfangen die nicht reproduzierbar sind, sondern nur zufällig entstehen. Das menschliche Vorstellungsvermögen (Gehirn) ist nicht dafür ausgelegt alle Eventualitäten zu erkennen die bei der verschachtelten Ausführung auftreten können.
Für den geringen Nutzen, geht kaum Jemand diesen Aufwand und vor allem nicht das Risiko ein.
-
Aber aber... ok.
-
Was dauert eig. an der Threraderzeugung so lange?
Eigentlich muss doch nur ein bischen Speicher für Stack und Register alloziert werden sowie dem Scheduler bekannt gemacht werden. Aber sonst?Höchstens noch threadlocal data, aber das ist doch meistens auch gratis, wenn man es nicht nutzt.
-
"Thread start: few hundred microseconds"
Das ist nicht "lange" aus Sicht des menschlichen Benutzers. Es ist ein nicht auszurottendes Gerücht, dass Treaderzeugung wahnsinnig teuer ist. Aus Ghz-Sicht im Nanosekundenbereich ist es nicht ganz billig.
Ansonsten: Threadpools und nochmal Threadpools.
-
Ja, das hat mich als Argument eben auch verwundert. Mir geht es nicht darum Performance zu verbessern (wobei ich glaube, dass die meisten Algorithmen, die man parallelisieren möchte, oft auch nicht durch das Erstellen des Threads so stark ausgebremst werden), sondern eben ausschließlich um Benutzerfreundlichkeit.
Und es geht eben um Dinge, die halt etwas länger als ein paar Sekunden dauern würden.
Also ein Beispiel, was mir wieder vor kurzem begegnet ist: Ich habe ein Programm mit mehreren Tabs. Das Programm ist hochgradig datenbanklastig; beim Klicken auf ein bestimmtes Tab wird automatisch eine aufwendige Datenbankabfrage gestartet. Man kann allerdings auch filtern! Wenn ich vorher weiß, dass ich filtern will, die Standardabfrage allerdings 10 Sekunden dauert, stört mich das schon Mal erheblich.
Die UI-Datentabelle zu locken und das Laden in einen anderen Thread auszulagern und eben eine Abort-Injection anzubieten, klingt für mich nicht nach besonders viel Aufwand (etwas Ähnliches habe ich vor kurzem implementiert)... Na ja, die einfachere Lösung wäre in diesem Fall vermutlich einfach gar nichts zu laden, bevor ein Filter eingegeben wird. Aber manchmal will Benutzer eben eine Standardabfrage aber ein aufwendiges Laden unterbrechen können. Und auch wenn das nicht sein muss, finde ich, dass man als Benutzer ein besseres Gefühl vom ganzen "Anwendungsfluss" hat, also dass es irgendwie zügiger geht, schnell reagiert und brav rasch reagiert.
Vielleicht bin ich als ungeduldiger Benutzer auch einfach die Minderheit.