Verteilte und Parallele Programmierung

PD Stefan Bosse
Universität Bremen, FB Mathematik & Informatik
SS 2020
Version 2020-06-10

Parallele Programmierung


Überblick

Lua :: Daten und Variablen

  • Variablen werden mit dem Schlüsselwort local definiert Erzeugung eines Datencontainers!

  • Es gibt keine Typendeklaration in Lua! Kerntypen:

    Tcore={number, boolean, table, string, function}

  • Alle Variablen sind polymorph und können alle Werttypen aufnehmen (auch dynamisch wechselnd zur Laufzeit).

  • Bei der Variabledefinition kann ein Ausdruckswert zugewiesen werden

local v = ε,..;  v = ε; 

Lua :: Funktionen

  • Funktionen können mit einem Namen oder anonym definiert werden

  • Funktionen sind Werte 1. Ordnung Funktionen können Variablen oder Funktionsargumenten zugewiesen werden

  • Eine Funktion kann einen Wert mit der return Anweisung zurückgeben. Ohne explizite Wertrückgabe undefined

  • Es wird nur Call-by-value Aufruf unterstützt - jedoch werden Objekte, Funktionen und Arrays als Referenz übergeben; Parameter pi sind an Funktionsblock gebunden

function name (p1,p2,..) statements ; return ε end  name(ε1,ε2,..)

Lua :: Funktionen

  • Da in JavaScript Funktionen Werte erster Ordnung sind können

    • Funktionen an Funktionen übergeben werden und
    • Funktionen neue Funktionen zurückgeben (als Ergebnis mit return)
  • Es können daher anonyme Funktionen function (..) {..} definiert werden die entweder einer Variablen als Wert oder als Funktionsargument übergeben werden.

local x = function (pi) ε(pi) end
array.forEach(function(elem,index) ε(pi) end

Lua :: Datenstrukturen

In Lua sind Objekte universelle Datenstrukturen (sowohl Datenstrukturen als auch Objekte) die mit Hashtabellen implementiert werden. Arrays werden in Lua ebenfalls als Hashtabelle implementiert!. D.h. Objekte == Datenstrukturen == Arrays == Hashtabellen.

  • Es gibt kein nutzerdefinierbares Typensystem in Lua.

  • Eine Datenstruktur kann jederzeit definiert und verändert werden (d.h. Attribute hinzugefügt werden)

local dataobject = {
  a=ε,
  b=ε, ..
  f=function () { .. }
}
..
dataobject.c = ε

Lua :: Datenstrukturen

  • Dadurch dass Objekte und Arrays mit Hashtabellen implementiert (d.h. Elemente werden durch eine Textzeichenkette referenziert) werden gibt es verschiedene Möglichkeiten auf Datenstrukturen und Objektattribute zuzugreifen:
dataobject.attribute
dataobject["attribute"]
array[index]
array["attribute"]

Lua :: Objekte

  • Objekte zeichnen sich in der objektorientierten Programmierung durch Methoden aus mit der ein Zugriff auf die privaten Daten (Variablen) eines Objekts möglich wird.

  • In Lua kann auf Variablen eines Objekts (die Attribute) immer direkt zugegriffen werden.

  • Attribute können Funktionen sein - jedoch können die Funktionen nicht wie Methoden direkt auf die Daten des Objektes zugreifen.

  • Daher definiert man Methoden über Prototypenerweiterung in Lua.

  • Die Methoden können über die self Variable direkt auf das zugehörige Objekt zugreifen (also auch auf die Variablen/Attribute)

  • Es gibt eine Konstruktionsfunktion für solche Objekte mit Prototypendefinition der Methoden

  • Objekte werden mit dem new Operation durch die Konstruktionsfunktion erzeugt.

Lua :: Objekte

constructor=class()
function constructor:init (pi)
  self.x=ε
  ..
end
function constructor:methodi (..) {
  self.x=ε;
  ..
}
...
 
local obj =  constructor:new(..);

Lua :: Objekte

Lua - Ausführungsmodelle

Prozesse

  • Isolierte Programmprozesse ohne direkte Synchronisation und Dateaustausch zwischen den VMs

  • Synchronsiation nur über

    • Dateien
    • Sockets (lokal, TCP, UDP)
    • Pipes (Streams)
  • Jeder Prozess führt eine VM aus

Lua - Ausführungsmodelle

Threads

  • Es werden parallele Prozesse auf Threads abgebildet die bestenfalls 1:1 auf den CPUs / Cores ausgeführt werden, ansonsten durch einen Scheduler im Zeitmultiplexverfahren ausgeführt werden

  • Prozesse können synchronisiert auf geteilte Objekte (konkurrierend) zugreifen:

    • Channel
    • Semaphore, Mutex
    • Event, Timer
    • Shared Memory Store
  • Prozessblockierung blockiert den gesamten Thread (somit auch alle Fibers)

  • Jeder parallele Prozess in einem Thread läuft in eigener VM Instanz

  • Daten können nicht zwischen VMs ausgetauscht werden (Automatsisches Speichermanagement und GC) nur Austtausch über Serialisierung und Kopie von Daten!

Lua - Ausführungsmodelle

Fibers und Coroutinen

  • Es werden pseudo-parallele Prozesse (Coroutinen) auf Fibers abgebildet die grundsätzlich nicht parallel aber durch einen Scheduler im Zeitmultiplexverfahren ausgeführt werden.

  • Diese Prozesse können synchronisiert auf geteilte Objekte (nicht konkurrierend) zugreifen:

    • Channel
    • Semaphore
    • Event, Timer
  • Prozessblockierung blockiert nur einen Fiber

  • Alle parallelen Prozesse mit Fibers laufen in einer VM Instanz

Lua - Ausführungsmodelle

figthreadsjs


Abb. 1. Threadmodell und Kommunikation der Prozesse mit geteilten Objekten

Lua - Ausführungsmodelle

  • Neben Thread, Fibers, und Prozessen kann auch die Parallelisierung von Ein- und Ausgabeoperation genutzt werden

  • Asynchrone IO wird sowohl in nodejs (JavaScript) als auch in Lua (lvm) mittels der libuv Bibliothek implementiert

    • Verwendung von Callback Funktionen für die Daten- und Ereignisverarbeitung
    • Anders als in JavaScript (nodejs) wird asynchrone IO in Lua eher seltener verwendet
  • Fibers (Coroutinen) werden in Lua direkt durch die Lua VM verarbeitet

  • Threads werden über die libuv einzelnen VM Instanzen zugeordnet

    • Verbindung der Instanzen über libuv
    • Jede VM Instanz hat ihre eigene Event Loop!

Lua - Ausführungsmodelle