Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Strippen ziehen - Nebenläufigkeit in modernen Programmiersprachen

Strippen ziehen - Nebenläufigkeit in modernen Programmiersprachen

A talk in German about concurrency in modern programming languages
Mathema Campus, 2024-04-13

Kotlin kennt Coroutinen, C# und Java (virtuelle) Threads. Dart und JavaScript sind single-threaded, ermöglichen aber trotzdem eine asynchrone Programmausführung. Der Wunsch, Dinge (quasi) gleichzeitig tun zu können, ist praktisch so alt wie das Programmieren selbst. Sobald es die Hardware hergegeben hat, wurden entsprechende Konzepte ersonnen und umgesetzt. Und nein, Coroutinen wurden nicht für Kotlin erfunden. In diesem Vortrag sehen wir uns moderne Umsetzungen an. Dabei geht es nicht um die Frage, welche Sprache es besser macht, sondern zum einen um Begriffserklärungen (was bedeuten Nebenläufigkeit und Asynchronität eigentlich?), und zum anderen um die Nutzung im Code. Was gehört zur Programmiersprache, was zur (Klassen-)Bibliothek?

Thomas Künneth

April 13, 2024
Tweet

More Decks by Thomas Künneth

Other Decks in Technology

Transcript

  1. Dinge gleichzeitig erledigen • Gegner und Gegenstände in einem Spiel

    bewegen • Anfragen von entfernten Computern beantworten • Ein komplexes Problem verteilt lösen
  2. Wie gleichzeitig ist gleichzeitig? • Abhängig von verwendeter Soft- und

    Hardware • Fähigkeiten (Architektur) des Systems • Oft nur „gefühlt gleichzeitig“
  3. 1980er • Ära der Home Computer • Einfach gestrickte Hardware

    • Maschinen sehr langsam • „Betriebssystem“ Kombination aus BASIC Interpreter und Editor
  4. • Programme wurden oft in BASIC geschrieben • Einfach zu

    lernen • Langsam • Wer konnte, wich auf Maschinensprache aus
  5. • Die meisten Mikroprozessoren führten immer genau ein Programm aus

    • Reaktion auf Ereignisse durch „Interrupts“ • Tastatur abfragen • Cursor blinken lassen
  6. • Hauptprogramm wird unterbrochen • „Interrupt-Routine“ wird ausgeführt • Hauptprogramm

    wird fortgesetzt • Je nach Prozessor verschiedene Interrupt-Quellen
  7. • Commodore BASIC selbst aus damaliger Sicht unkomfortabel • Manche

    Dialekte boten PAUSE oder DELAY an (keine Möglichkeit, während des Wartens etwas zu tun) • In BASIC (zunächst) kein Pendant zu Interuptroutinen
  8. • Manche Dialekte boten Zugriff auf Systemzeit (Variablen TI oder

    TIME$) • Besser geeignet, weil Dauer für Hochzählen von Variablen abhängig von Geschwindigkeit des Rechners • Hat man aber noch nicht gewusst – oder ignoriert ;-)
  9. • Aktualisierung von Bedienelementen auf der Basis von Zustand •

    Zustand greift auf Flows zurück • Flows werden aus Coroutinen gespeist
  10. • Aktualisierung von Bedienelementen auf der Basis von Zustand •

    Zustandsänderungen explizit mit setState() • Wiederholte Ausführung von Code mit Timer.periodic()
  11. • Promise repräsentiert (irgendwann vorliegendes) Ergebnis eines asynchronen Aufrufs •

    Definition asynchroner Funktionen mit async • Warten auf Ergebnis mit await • Währenddessen kann System andere Dinge tun
  12. • Kein Observable-ähnlicher Zustand in purem JavaScript/HTML • Wohl aber

    in Web Frameworks wie React • React macht deklarative UI-Frameworks populär • Inspiration für Flutter, SwiftUI und Jetpack Compose
  13. • Warten auf ein Ereignis erlaubt dem System, bis zum

    Eintreten etwas anderes zu tun • Sinnvoll, wenn nur ein Thread für die Ausführung von Code zur Verfügung steht
  14. • Im Kern sind Dart- und JavaScript-Umgebungen single-threaded • Zentrales

    Element in beiden Fällen event loop • Langlaufender Code verhindert Abarbeiten der event loop • Zeigt sich durch nicht reagierende Benutzeroberfläche
  15. • Verfügbarkeit mehrerer Threads macht UI nicht automatisch immun •

    Praktisch alle UI-Frameworks der letzten 40 Jahre sind single- threaded • Ist dieser ausgelastet, steht die Anwendung
  16. Nebenläufigkeit ist die Fähigkeit eines Computersystems, mehrere Aufgaben oder Teile

    eines Programms scheinbar gleichzeitig auszuführen. Diese Aufgaben oder Teile können in ihrer Ausführung zeitlich überlappen. Sie müssen nicht einzeln, in einer bestimmten Reihenfolge ausgeführt werden.
  17. Asynchrone Programmierung erlaubt, Aufgaben auszuführen, ohne den Hauptausführungsfluss eines Programms

    zu blockieren. Statt auf den Abschluss einer langwierigen Operation zu warten, kann das Programm mit anderen Aufgaben fortfahren. Es wird benachrichtigt, wenn das Ergebnis der lang laufenden Operation verfügbar ist.
  18. In der ereignisorientierten Programmierung wird der Ablauf des Programms in

    erster Linie durch Ereignisse bestimmt. Ereignisse können beispielsweise Benutzereingaben, Alarme / Timer oder Ergebnisse von Netzwerkoperationen sein.
  19. Unter reaktiver Programmierung wird die Verarbeitung von kontinuierlichen und asynchronen

    Datenströmen verstanden. Datenströme transportieren Ereignisse, Zustandsänderungen, Fehler, sowie beliebige andere Arten von Informationen.