Übung 6: Parallel Lua / CSP Tutorial - Nachrichtenbasierte Kommunizierende Prozesse (Stefan Bosse) [7.2025]

Übung 6 - Parallel Lua / CSP Tutorial - Nachrichtenbasierte Kommunizierende Prozesse

Übung 6 - Parallel Lua / CSP Tutorial - Nachrichtenbasierte Kommunizierende Prozesse
Vorbereitung und Verwendung
Channel
Der Alt Prozesskonstruktor
Kommunizierende Prozesse

Vorbereitung und Verwendung

Minimalanforderungen: lvm 1.1.18, luv 2.7.5

  1. Der Programmcode kann in dem oberen Teilfenster eines Snippets verändert werden.
  2. Der Programmcode wird ausgeführt durch Drücken der Playtaste ▸ im unteren Teilfenster (Ausgabekonsole).
  3. Die Ausgabekonsole kann auf der rechten Seite gelöscht werden durch Drücken von ✗.
  4. Hin und wieder kann eine Aktualisierung des Ausgabefensters durch Drücken des Knopfes ↻ erforderlich sein.
  5. Bei parallelen Prozessen werden jeweils neue VM Instanzen in Threads gestartet. Wenn etwas schief läuft kann das Programm hängen und nicht terminieren (also der aktuelle Codeabschnitt). Der Abbruch kann versucht werden durch Drücken des Knopfes ◼.

Ein Beispiel

 ▸ 
 ◼ 
 ✗ 
 ↻ 
 ≡ 

Channel

Der Kommuniaktionskanal wurde bereits eingeführt. Hier noch einmal die Zusammenfassung:


Ein Beispiel: Verwendung eines Chennels in Par Prozessen

 ▸ 
 ◼ 
 ✗ 
 ↻ 
 ≡ 

Aufgabe 1. 1. Füge eine Zeitmessung ein indem die log Funktion verwendet wird (anstelle print), sowohl vor als auch nach den Kanaloperationen. Füge vor dem Lesen aus dem Kanal eine Verzögerung sleep(100) ein. Wie ist das zeitliche Verhalten? 2. Was passiert wenn der Kanal mit n=0 (kein Puffer) erzeugt wird?

LS0gMS4gV3JpdGUgd2lyZCBuaWNodCBibG9ja2llcnQgdW5kIGRlciBQcm96ZXNzIDIgYXJiZWl0ZXQgdW5hYmjDpG5naWcgdm9uIFByb3plc3MgMQotLSAgICBELmguIChQMSAvLyBQMikgCi0tIDIuIFdyaXRlIHVuZCBSZWFkIHNpbmQgZ2Vrb3BwZWx0LCB1bmQgKFAxIHx8IFAyKSwgV3JpdGUgd2lyZCB2ZXJ6w7ZnZXJ0IApyZXF1aXJlICJDc3AiCmxvY2FsIGNoID0gQ2hhbm5lbCgxKQpsb2NhbCBjaCA9IENoYW5uZWwoMCkgIC0tIDIuClBhcih7CiAgZnVuY3Rpb24gKCkKICAgIHNsZWVwKDEwMCkKICAgIGxvZygiQmVmb3JlIFJlYWQiKQogICAgbG9jYWwgeCA9IGNoOnJlYWQoKQogICAgbG9nKCJDb25zdW1lZCAiLi54KQogIGVuZCwKICBmdW5jdGlvbiAoKQogICAgbG9jYWwgeCA9ICJEYXRhIgogICAgbG9nKCJQcm9kdWNpbmcgIi4ueCkKICAgIGNoOndyaXRlKHgpCiAgICBsb2coIkFmdGVyIFdyaXRlIikKICBlbmQKfSx7CiAgY2g9Y2gKfSk=

Der Alt Prozesskonstruktor

Der Alt Prozesskonstruktor implemtiert einen mutualen Ausschluss auf möglicherweise parallelen Ereignissen, und führt eine Auswahl und Sequenzialisierung ein. So kann mit einem Alt Prozesse parallel auf das Eintreten von Ereignissen gewartet werden, prominent das Warten auf Daten in mehreren Kanälen.


Ein Beispiel: Verwendung eines Alt Prozesses in Par Prozessen

 ▸ 
 ◼ 
 ✗ 
 ↻ 
 ≡ 

Aufgabe. Welcher Wert wird ausgegeben? Was passiert wenn vor dem Alt Operator ein Wert in den Channel 2 geschrieben wird (also ch2:write("B"), fügre ein sleep(100) vor dem Alt Operator ein)?


Kommunizierende Prozesse

In dieser Aufgabe sollen mehrere Prozesse mit einem Verwaltungsprozess kommunizieren. Der Verwaltungsprozess verwaltet und verteilte geteilte Ressourcen ohne Deadlock Gefahr. Ein Beispiel ist nachfolgend die Implementierung eines Semaphor durch einen Prozess. Die anderen Prozesse fragen die Ressource über Kommunikationskanäle an, und bekommen die Antwort über einen Kommunikationskanal. Es gibt zwei Kanäle pro Prozess und Ressource:

  1. Anfrage (Request)
  2. Antwort (Reply)

#semchann

Die Dinierenden Philosophen sind der Klassiker um Deadlock Szenarien und das randomisierte Verhalten von parallelen Systemen zu demonstrierem.

require('Csp')
local s = {Semaphore(1),Semaphore(1),Semaphore(1)}
local b = Barrier(3)
local function eat(id)
  print('Eating '..id)
end
local function think(id)
  print('thinking '..id)
end
Par({
  function () b:await(); for i = 1,10 do
    s[1]:down(); s[2]:down(); eat(1); s[2]:up(); s[1]:up(); think(1) 
  end end,
  function () b:await(); for i = 1,10 do
    s[2]:down(); s[3]:down(); eat(2); s[3]:up(); s[2]:up(); think(2) 
  end end,
  function () b:await(); for i = 1,10 do
    s[3]:down(); s[1]:down(); eat(3); s[1]:up(); s[3]:up(); think(3)
  end end
})
print('Done.')

Aufgabe. Implementiere die Dinierenden Philosophen mit einem zentralen Verwaltungsprozess der die N Gabeln verwaltet. Die Anfrage von Gabeln erfolgt über Kommunikationskanäle. Der Alt Prozesskonstruktor muss vom Verwaltungsprozess verwendet werden um auf allen Anfragekanälen Nachrichten empfangen zu können.


Implementierung der Dinierenden Philosophen ohne Deadlock mittels Alt, Par, und Kommunikationskanälen für Anfrage und Bestätigung von Ressourcen (hier die Gabeln)

 ▸ 
 ◼ 
 ✗ 
 ↻ 
 ≡ 

PGI+bG9jYWw8L2I+IGNoX3AxX3JlcSA9IENoYW5uZWwoMSkKPGI+bG9jYWw8L2I+IGNoX3AxX3JlcCA9IENoYW5uZWwoMSkKUGFyKHsKICA8Yj5mdW5jdGlvbjwvYj4gKCkgCiAgICAtLSBQaGlsbyAxCiAgZW5kLAogIDxiPmZ1bmN0aW9uPC9iPiAoKSAKICAgIC0tIFBoaWxvIDIKICBlbmQsCiAgLS0gLi4uLgogIDxiPmZ1bmN0aW9uPC9iPiAoKQogICAgLS0gVmVyd2FsdHVuZwogICAgQWx0KHsKCiAgICB9KQogIDxiPmVuZDwvYj4KfSx7Cgp9KQ==

Frage 4. Wie müssen die Gabeln angefragt werden damit kein Deadlock auftreten kann? Können die Gabeln sequenziell nacheinander angefragt werden? Wo wird Atomarität verletzt (siehe auch Test & Set Probleme).

  1. Paarweise - es gibt aber keine operationale Unterstützung dafür; ggfs. Verwendung eines globalen Mutex Locks (Schutz aller Gabeln) oder paarweise Lock (Schutz eines Paares)
  2. Die Atomarität wird bei der Sequenz down-down verletzt. Selbst wenn man voher die Verfügbarkeit testet ist der Zugriff danach nicht mehr garantiert. Aber es gibt sems-try-down Operationen die wengistens bei verlorenen Wettbewerb nicht blockieren (und wenn schon erfolgt kann die erste ressource wieder freigegeben werden.



Hilfe



Einreichung (Assignment #2025-90824 )



Prüfen



Bewerten (Lehrer)




Created by the NoteBook Compiler Ver. 1.36.4 (c) Dr. Stefan Bosse (Tue Jul 08 2025 17:16:30 GMT+0200 (Central European Summer Time))