Die Lösung für nebenläufiges Denken: Promises

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Chromanoid » 14.01.2016, 00:13

Gerade auf Reddit gesehen: https://github.com/vasanthk/async-javascript/ "Evolution of Asynchronous JavaScript" passt zum Thema :)
Benutzeravatar
Chromanoid
Christian Kulenkampff
Moderator
 
Beiträge: 3644
Registriert: 16.10.2002, 19:39
Wohnort: Lüneburg
Alter Benutzername: atr_23

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Alexander Kornrumpf » 14.01.2016, 11:49

Chromanoid hat geschrieben:Ich glaube hier ist wieder unser unterschiedliches Verständnis von Nebenläufigkeit das Problem. So wie ich das gelernt habe, gilt nur weil etwas sequentiell ausgeführt wird noch nicht, dass es nicht zwei Prozesse sind, die nebenläufig zu einander ausgeführt werden (siehe https://books.google.de/books?id=9dKYNO ... &q&f=false). Da die Generatoren in node.js ja scheinbar auch auf externe Ressourcen warten können und dann andere Callbacks ausgeführt werden, ist die Reihenfolge der Operationen nicht mehr total sondern nur noch partiell geordnet und dann spricht man meines Wissens nach von Nebenläufigkeit. Callbacks oder auch Interrupts sind deswegen meiner Interpretation nach auch eine Form der Nebenläufigkeit, es gibt nämlich keine totale Ordnung der Anweisungen, siehe https://www.informatik.uni-hamburg.de/T ... script.pdf S. 3 bzw. https://www4.cs.fau.de/Lehre/SS08/V_SPI ... /H2-A6.pdf S. 1. Aber das ist wirklich ein ziemliches Herumgereite auf den Definitionen und ich lasse mich gerne eines Besseren belehren.

[...]

Genauso auch die Programmteile, die mit yield auf etwas warten.



Geschenkt. Ich schreib nochmal worauf ich hinaus will:

Yield hält den Generator an und übergibt einen Wert an den Aufrufer. Der Aufrufer kann einen Wert zurück an das yield geben und damit den Generator an dieser Stelle fortsetzen. Die Reihenfolge in der das passiert ist vollkommen deterministisch. Yield definiert also einen Punkt an dem der Generator angehalten und gestartet werden kann. Wenn du so willst ein Funktionskopf und return an derselben Stelle. Zu sagen yield würde auf etwas "warten" ist so wie zu sagen, eine Funktion würde darauf warten aufgerufen zu werden. Yield führt nicht mehr Nebenläufigkeit ein, als ein Funktionsaufruf, denn: Ein Generator ist keine Koroutine!

Was hier passiert ist, dass schlaue Menschen erkannt haben, dass man Koroutinen "elegant" mit Generator-Syntax implementieren kann. Was die Beispiele des Threaderstellers nicht zeigen, wohl aber dein Link zu Generatoren, ist dass nicht das yield auf ein asynchrones Ereignis wartet, sondern das andere Ende was dann, wenn das Ereignis eintritt, den Generator fortsetzt. Deswegen "invertiert" bzw. "von hinten aufgezäumt". Im Ergebnis sieht es so aus, als würde yield darauf warten. Die Magie liegt aber nicht im yield sondern in Coroutine. Alle Nebenläufigkeit (nach deiner Def.) wird durch Coroutine (eine Funktion des Promise-API) eingeführt, nicht durch den Generator. Es ist ein Pattern, das Generatoren verwendet, kein Sprachkonstrukt.
Alexander Kornrumpf
Moderator
 
Beiträge: 1611
Registriert: 25.02.2009, 14:37

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Chromanoid » 14.01.2016, 13:08

Ah, ich verstehe jetzt was Du meinst. Während das Sprachkonstrukt des Generators die Möglichkeit bereitstellt den Programmfluss einer Routine (die Generator-Routine) zu unterbrechen und später wieder aufzunehmen (eine wichtige Voraussetzung für Koroutinen), muss die Ausführung der verschiedenen Generator-Routinen noch in Bezug auf nebenläufige Ereignisse orchestriert werden, damit sie als nebenläufige Koroutinen funktionieren.
Benutzeravatar
Chromanoid
Christian Kulenkampff
Moderator
 
Beiträge: 3644
Registriert: 16.10.2002, 19:39
Wohnort: Lüneburg
Alter Benutzername: atr_23

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Alexander Kornrumpf » 14.01.2016, 13:44

Chromanoid hat geschrieben:Ah, ich verstehe jetzt was Du meinst. Während das Sprachkonstrukt des Generators die Möglichkeit bereitstellt den Programmfluss einer Routine (die Generator-Routine) zu unterbrechen und später wieder aufzunehmen (eine wichtige Voraussetzung für Koroutinen), muss die Ausführung der verschiedenen Generator-Routinen noch in Bezug auf nebenläufige Ereignisse orchestriert werden, damit sie als nebenläufige Koroutinen funktionieren.


Ja. Um nochmal auf Callbacks vs. Generatoren zurückzukommen, Ich glaube, dass die "gotchas" bei der Sache aus der Orchestrierung kommen, die das sagst du richtig, trotz single-threadedness, nicht transparent funktioniert (und wahrscheinlich auch nicht transparent sein kann, ich wüsste nicht wie). Die Orchestrierung ist aber für die Callbacks im Prinzip die gleiche, mit den gleichen "gotchas".

Dass man unabhängig davon eine Syntax subjektiv zugänglicher finden kann als eine andere bleibt davon natürlich unberührt. Generatoren sind sicher etwas worüber man mal einen Nachmittag nachdenken kann bevor man sie naiv einsetzt. Insofern nochmal danke, dass du mich bei besagtem Nachdenken unterstützt hast.
Alexander Kornrumpf
Moderator
 
Beiträge: 1611
Registriert: 25.02.2009, 14:37

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Chromanoid » 14.01.2016, 15:54

Ebenso Danke! Ohne Deine Hinweise, hätte ich von der Umsetzung eine falsche Vorstellung behalten. Das Generator-Konstrukt war mir vor dem Thema hier auch noch unbekannt. In Python und wohl noch einigen anderen Sprachen gibt es ähnliche Implementierungen von Koroutinen damit. Echte parallele Verarbeitung ist mir da irgendwie lieber. Das Argument aus http://blog.stevenedouard.com/asynchron ... ncurrency/ für node.js, bei IO als Flaschenhals, hatte mich noch etwas irritiert:
C# runtime doesn’t scale as well to I/O-bound tasks like loading washing machines, primarily due to the overhead of context switching of threads, it does scale better at computationally intensive, CPU-bound tasks.
Dem scheint wirklich so zu sein, da .NET wohl einen Threadpool für IO-Aufgaben hat (siehe http://stackoverflow.com/questions/8905 ... e-js-possi). Ich glaube Java ist an der Stelle rudimentärer und sollte dieses Problem nicht haben.
Benutzeravatar
Chromanoid
Christian Kulenkampff
Moderator
 
Beiträge: 3644
Registriert: 16.10.2002, 19:39
Wohnort: Lüneburg
Alter Benutzername: atr_23

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon KayZ » 16.01.2016, 19:47

@antisteo: Ich muss einfach mal Dart in den Raum werfen. Bei Dart ist das ganze async-Zeug direkt Teil der Programmiersprache und aller APIs ohne dass es unterschiedliche Implementationen durch verschiedene Libraries gibt. Und sie decken wirklich alles ab, also nicht nur Futures sondern auch Streams (asynchrone Listen) und es gibt auch await, so dass man dort nicht mal die beispielhaft genannte 100 fache Verkettung von Futures/Promises machen muss, sondern man kann es nahezu wie synchronen Code schreiben.

Also zum Beispiel statt:
Code: Ansicht erweitern :: Alles auswählen

HttpServer.bind('127.0.0.1', 4444)
  .then((server) => print('${server.isBroadcast}'))
  .catchError(print);
 

kann man auch:
Code: Ansicht erweitern :: Alles auswählen

try {
  var server = await HttpServer.bind('127.0.0.1', 4444);
  print('${server.isBroadcast}');
} catch (e) {
  print(e);
}
 

schreiben.

https://www.dartlang.org/docs/tutorials/futures/
https://www.dartlang.org/docs/tutorials/streams/

Im zweiten Link sieht man das ganze anhand eines asynchronen Generators dessen Werte innerhalb einer await for Schleife abgerufen werden und dessen Ergebnis eine Future ist. Der Code liest sich, abgesehen von ein paar keywords, wie synchroner Code.

Warum ich Dart in den Raum werfe? Man kann Dart für clientseitige als auch für serverseitige Anwendungen nutzen. Im Browser kompiliert man es nach Javascript (im Normalfall performanter als handgeschriebenes JS und durch Treeshaking (nur wirklich verwendeter Code wird in JS umgewandelt) teilweise auch kleiner als eine JS-Anwendung mit x-Libs die man so benötigt um halbwegs vernünftiges JS schreiben zu können) und auf dem Server läuft es nativ. Wie in Javascript gibt es in Dart nur einen Thread, man kann aber mehrere "Isolates" erzeugen die allerdings nur über Nachrichten miteinander kommunizieren können (es gibt keinen globalen Speicherbereich in dem mehrere Isolates rumhantieren und sich gegenseitig in die Quere kommen können, also keine concurrent modification exceptions möglich, wie man sie z.B. aus Java kennt).
KayZ
Dennis
 
Beiträge: 42
Registriert: 06.01.2015, 00:46

Re: Die Lösung für nebenläufiges Denken: Promises

Beitragvon Alexander Kornrumpf » 22.01.2016, 15:28

Hier macht es jemand live mit python vor:

http://pyvideo.org/video/3432/python-co ... nd-up-live
Alexander Kornrumpf
Moderator
 
Beiträge: 1611
Registriert: 25.02.2009, 14:37

Vorherige

Zurück zu Algorithmen und Datenstrukturen

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron