Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander...

42
Prozesskoordination Prof. Dr. W. Riggert

Transcript of Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander...

Page 1: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Prozesskoordination

Prof. Dr. W. Riggert

Page 2: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Ausgangssituation

Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX.

Zwei Prozesse heißen nebenläufig, wenn sie unabhängig voneinanderverarbeitet werden. Für nebenläufige Prozesse ist es gleich, ob

• erst A und dann B• erst B und dann A• A und B gleichzeitig

ausgeführt werden.

Mit Nebenläufigkeit ist ein Wettstreit um knappe Betriebsmittel einesRechners verbunden. Zwei nebenläufige Prozesse sind also bezüglich ihresAblaufs unabhängig, um Ressourcen konkurrieren sie sehr wohl unter-einander. Daher kann durch wechselseitige oder gemeinsame Nutzung derBetriebsmittel ein Konflikt entstehen.

Page 3: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Konfliktbeispiel

Eine Druckerwarteschlange besteht aus durchnummerierten Einträgen undentsprechenden Dateinamen. Die Variable OUT verweist auf den nächstenzu druckenden Eintrag, IN auf den nächsten freien. Auf beide Variablehaben alle Prozesse Zugriff. Seien die Einträge 0-3 leer und 4-6 belegt, sodass OUT=4 und IN=7 ist. Prozess A und B entscheiden sich gleichzeitig,eine Datei zu drucken :

1. A liest IN ein und speichert ihren Wert 7 lokal.2. Der Prozessor wechselt von A nach B.3. B liest IN ein, speichert seine zu druckende Datei an Eintrag 7 und erhöht IN auf 8.4. Der Prozessor wechselt zu A und findet in IN noch den Wert 7. Er überschreibt den dort gefundenen Dateinamen von B und setzt seinerseits IN auf 8.5. Das Spoolverzeichnis ist konsistent, so dass der Druckprozess keinen Fehler erkennt. Der Druckauftrag von B wird allerdings nie ausgeführt

Page 4: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Bei einer parallelen Verarbeitung kann man im allgemeinen keine Angaben über die relative Geschwindigkeit der beteiligten Prozesse machen. Benutzen mehrere Prozesse eine Ressource gemeinsam, kann es zu beliebigen Verzahnungen kommen :

Führt ein Prozess die Zuweisung x = 275 aus, ein anderer parallel dazu x = 389 , so ist nicht klar, ob x schließlich den Wert 275 oder 389 erhält oder gar einen völlig anderen Wert, der aus einer Mischung der Bitmuster von 275 und 389 entsteht.

Wechselseitiger Ausschluss 1

Page 5: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Wechselseitiger Ausschluss 2

Bei zwei nebenläufigen Prozessen lässt sich der relative Bearbeitungsfortschritt nicht vorhersagen.

concurrency-example.cc#include <ostream.h>#include "concurrent.h"int a=1, b=2;f(){ a=a+b; a=2*a; }g(){ a=5; }main(){concurrent(f,g); // nebenlaeufiger Aufrufcout << a;}

Die Aufrufe von f und g erfolgen nebenläufig. Welcher Wert von a wird am Ende ausgegeben?

Page 6: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Wechselseitiger Ausschluss 2a

Lösungsvielfalt: Mehrere zeitliche Abfolgen für die Ausführung der

Wertzuweisungen sind möglich:

Page 7: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Wechselseitiger Ausschluss 3

Wenn zwei unabhängige Prozesse auf gemeinsame Daten zugreifen,kann es zu Kollisionen kommen, da der Scheduler zu einem unvorhersehbarenZeitpunkt zwischen ihnen umschalten kann. Dies ist nur solange kein Problem,wie jeder Prozess seine eigenen Variablen besitzt.

Page 8: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Kritischer Bereich 1

DefinitionEs sei nun eine Anzahl F von Prozessen gegeben, die eine gemeinsameRessource x benutzen. Ist A eine Anweisungsfolge eines Prozesses P ausF , in der x benutzt wird, d.h. existiert eine Anweisungsfolge in mehreren Prozessen, in der auf die gemeinsame Ressource x zugegriffen wird, dann heißt A kritischer Bereich von P .

Um unvorhergesehene Effekte zu vermeiden, ist darauf zu achten, dass sichnicht zwei Prozesse aus F gleichzeitig in kritischen Bereichen befinden, von denen einer x verändert, d.h. falls ein Prozess eine gemeinsame Ressourcenutzt, schließt er alle anderen von deren Gebrauch aus. Da dieser wechselseitige Ausschluss eine Einschränkung der Parallelitätbedeutet, sollten die kritischen Bereiche möglichst klein sein.

Page 9: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Bernstein-Bedingung

Wie findet man möglichst kleine kritische Bereiche? oder umgekehrtwann können Anweisungen A1,...,An gefahrlos parallel ausgeführt werden ?

Dies ist dann der Fall, wenn sie konfliktfrei sind, d.h. für i<>j keine in Ai gelesene oder geschriebene Variable in Aj geschrieben wird (Bernstein 1966).

Page 10: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Kritischer Bereich 2

Parallele Prozesse sind so zu programmieren, dass ihre kritischen Bereiche

als unteilbare Aktionen unter Ausschluss der übrigen Prozesse ausführt

werden.

Um diesen Zustand zu erreichen, sind vier Bedingungen notwendig :1.Gegenseitiger Ausschluss (mutex): Wenn sich ein

Prozess in seinem kritischen Bereich befindet,darf kein anderer Prozess den

entsprechenden Bereich ausführen. 2. Kein Verhungern (starvation): Ein Prozess soll

nicht unendlich warten, bis er den kritischen Bereich betreten darf.

3. Sofortige Entscheidung (indefinite postponement): Wenn mehr als ein Prozess den kritischen Bereich betren wollen, muss sofort entschieden werden, welcher die Erlaubnis erhält.

4. Echter Wettbewerb: Prozesse ausserhalb des kritischen Bereichs dürfen keinen anderen Prozess daran hindern, diesen zu betreten.

Page 11: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Verbot von Interrupts

Ablauf :

Jeder Prozess sperrt vor Eintritt in seinen kritischen Bereich alle Unter-brechungsmöglichkeiten durch andere Prozesse und lässt Interrupts erstnach Verlassen des kritischen Bereichs wieder zu.

Problem :

Die Prozessverarbeitung erfolgt korrekt, jedoch hat ein Benutzerprozess das Recht, systemseitige Unterbrechungen zu verhindern und damit Systemaufgaben zu blockieren.

Page 12: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Sperrsynchronisation 1

Prozesse synchronisieren sich über die Sperre eines Objekts x :

• Prozesse bewerben sich um die Sperre von x . • Ist diese gesetzt, müssen sie warten. • Ansonsten darf einer der Prozesse sie setzen, um alle anderen auszuschließen • Benötigt ein Prozess die Sperre nicht mehr, hebt er sie auf, so dass andere Prozesse an die Reihe kommen können.

Page 13: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Sperrsynchronisation 2

Beispiel:1. Sei S eine Betriebsmittelvariable und mit S=0 initialisiert.2. Ein Prozess P erhält die Berechtigung, das Betriebsmittel anzufordern, setzt S=1 und tritt in den kritischen Bereich ein.3. S=1 zeigt konkurrierenden Prozessen zu P an, dass sie warten müssen, bis S auf den Wert 0 zurückgesetzt ist.4. S=0 bedeutet, dass sich kein anderer Prozess im kritischen Bereich befindet, S=1 heißt, ein Prozess hat den kritischen Bereich betreten.

Problem :Liest ein Prozess P die Variable mit S=0 ein und findet sofort ein Prozess-wechsel zu R statt, kann auch R die Variable S von 0 auf 1 setzen. Kehrtdas Ausführungsrecht zu P zurück (obwohl R sich noch im kritischen Bereichbefindet), weist er S den Wert 1 zu. Beide Prozesse befinden sich nun imkritischen Bereich.

Page 14: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Striktes Alternieren 1

Beispiel:Für zwei Prozesse gelte folgende Sequenz :

Prozess 0 : while (S != 0) warte ...... Kritischer Bereich S := 1 nichtkritischer Bereich Prozess 1 : while (S != 1) warte ...... Kritischer Bereich S := 0 nichtkritischer Bereich

Page 15: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Striktes Alternieren 2

Ablauf :1. S ist mit dem Wert 0 initialisiert2. Prozess 0 stellt fest, dass S den Wert 0 besitzt und betritt den kritischen Bereich3. Prozess 1 erkennt ebenfalls, dass S=0 gilt und wartet4. Prozess 1 befindet sich im Zustand bereit, bis Prozess 0 den kritischen Bereich verlässt und S auf 1 setzt.5. Durch die wechselseitige Benutzung von S können beide Prozesse alternierend ihren kritischen Bereich betreten.

Page 16: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Striktes Alternieren 3

Problem :1. Die fortwährende Überprüfung des Wertes der Variablen S verschwendet Rechenzeit. 2. Die dritte notwendige Bedingung wird verletzt, da bei ungleich schnellen Prozessen ein Prozess den anderen blockiert.3. Durchläuft Prozess 0 seinen kritischen Bereich sehr schnell und besitzt Prozess 1 einen langen nichtkritischen Bereich, befinden sich beide Prozesse im nichtkritischen Bereich mit S=1. Prozess 0 kann dann nicht in einen kritischen Bereich eintreten.

Page 17: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Warten und Benachrichtigen 1

Das strenge Schema der Synchronisation ist oft zu unflexibel :

Es kann während des Ausführens einer Anweisungsfolge notwendig werden, die Arbeit zu unterbrechen und darauf zu warten, dass ein anderer Prozesseinen bestimmten Zustand erreicht hat oder eine bestimmte Variable setzt. Dazu muß unter Umständen auch vorübergehend eine Sperre aufgehoben werden.

Man könnte dies natürlich durch Zerlegen der Anweisungsfolge erreichen, der logische Zusammenhang der Anweisungen würde aber verloren gehen.

Page 18: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Warten und Benachrichtigen 2

Es gibt zwei prinzipiell unterschiedliche Möglichkeiten, das Warten auf ein Bestimmtes Ereignis zu programmieren:

aktives Warten (”busy waiting“): Das Programm prüft innerhalb einer Schleife ständig, ob das erwartete Ereignis schon eingetreten ist.

”passives“ Warten durch Blockieren: Der Prozess benutzt einen Betriebssystemaufruf zum Warten. Er beauftragt das Betriebssystem,seine Ausführung solange zu suspendieren, bis das erwartete Ereigniseingetreten ist. Betriebssysteme beinhalten unterschiedliche Blockiermechanismenfür diesen Zweck. Das Betriebssystem muss beim Auftreten eines Ereignisses jeweils prüfen, ob ein oder mehrere Prozesse aufgeweckt werden müssen.

Page 19: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Warten und Benachrichtigen 3

aktives Warten (busy waiting) :

Der wartende Prozess führt eine Schleife der folgenden Form aus: while (!bedingung) {} «Fortsetzung» Da er dabei aktiv bleibt, belegt er unnötig Ressourcen. Man könnte das aktive Warten abmildern zu (polling and sleeping) while (!bedingung) { sleep(period) ; } «Fortsetzung» Auch dabei bleibt aber der Prozess unnötig semi-aktiv.

Günstiger ist es, einen Prozess ganz schlafen zu legen, bis sich diegewünschte Bedingung eingestellt hat.

Page 20: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Warten und Benachrichtigen 4

Prozess P ruft in einem für x synchronisierten Block die Funktionwait() auf. Anschließend geschieht in einer unteilbaren Aktion :

• P hebt die Sperre von x auf • P reiht sich in die Menge der Prozesse ein, die darauf warten,

die Sperre von x (wieder) zu bekommen, und legt sich schlafen.

Beim Aufwecken wird die Sperre nur aufgehoben, aber nicht weitergegeben.

Auch kann beim Aufwecken nicht davon ausgegangen werden, dass die Bedingung erfüllt ist, auf die man gewartet hat. Denn beim Schlafenlegen teilt ein Prozess ja nur mit, um welche Sperre er sich beim Aufwecken bewirbt.

Page 21: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Warten und Benachrichtigen 5

Ein mit wait() schlafengelegter Prozess kann erst dann fortfahren, wenn erdurch einen anderen wieder aufgeweckt wird. Im ungünstigsten Fall wird er nie mehr aufgeweckt.

Die Funktion wait darf nur von einem Prozess aufgerufen werden, der geradedie Sperre des zugehörigen Objekts hat.

Page 22: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Erzeuger-/Verbraucher-Problem 1

Ein Erzeuger produziert Informationen, ein oder mehrere Verbraucherverarbeiten sie weiter. Hier : Zwei Prozesse benutzen gemeinsam einen Puffer fester Größe.

Sind die Verbraucher in der Weiterverarbeitung unterschiedlich schnell, müssen die Informationen zwischengelagert = gepuffert werden. 1. Der Erzeuger will Informationen in einen vollen Puffer stellen - der Erzeuger legt sich schlafen und wird vom Verbraucher geweckt, wenn dieser Informationen entnimmt2. Der Verbraucher will einem leeren Puffer Informationen entnehmen - er legt sich schlafen und wird vom Erzeuger geweckt, falls dieser Informationen in den Puffer stellt.

Page 23: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Erzeuger-/Verbraucher-Problem 2

Ablauf :1. S bestimmt die Anzahl der Informationen im Puffer2. Der Erzeuger überprüft, ob S=n gilt. Falls ja, legt er sich schlafen, falls nein, stellt er weitere Informationen in den Puffer und erhöht S.3. Der Verbraucher prüft, ob S=0 gilt. Falls ja, legt er sich schlafen, falls nein, entnimmt er dem Puffer Informationen und dekrementiert S.

Problem:1. Der Puffer ist leer und der Verbraucher hat S gerade überprüft.2. Ein Prozesswechsel unterbricht den Verbraucher und startet den Erzeuger, ohne dass der Verbraucher sich schlafen legen konnte.3. Der Erzeuger schreibt Informationen in den Puffer und erhöht S. Er erkennt, dass S vorher den Wert 0 hatte und weckt den Verbraucher.4. Der Verbraucher hat aber nicht geschlafen, so dass das Wecksignal verloren geht. Erhält er aber das Ausführungsrecht, erkennt er noch, dass sein S den Wert 0 besitzt und legt sich schlafen.5. Der Erzeuger füllt den Puffer und legt sich ebenfalls schlafen. Beide Prozesse schlafen für immer.

Page 24: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Erzeuger-/Verbraucher-Problem 3

Im Beispiel wird sowohl beim Einfügen neuer Informationen, als auch beim Lesen der Informationen aktives Warten benutzt. Wenn ein Erzeuger und ein Verbraucher nebenläufig auf den Puffer zugreifen, sind damit grundlegende Anforderungen erfüllt:

• Das Senden und Empfangen von Informationen ist zu einem gewissen Grad Zeitlich entkoppelt. Solange Informationserzeugung und -verbrauch ungefähr mit gleicher Frequenz erfolgen, gibt es keine Probleme.• Ist die Informationserzeugung über längere Zeit zu schnell (Puffer voll), wird sie ”gebremst“, also mit der Verbrauchergeschwindigkeit synchronisiert.

Das gleiche gilt auch umgekehrt.Die Implementierung ist dennoch unzulänglich: Erzeuger und Verbraucher greifen auf gemeinsame Daten zu und modifizieren diese. Die Zugriffe sind keineatomaren Operationen, sondern unterbrechbare Befehlsfolgen. Dabei kann es zu nichtdeterministischem Programmverhalten (”race conditions“) kommen.

Page 25: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Semaphor 1

Sperrobjekte zur Sicherung kritischer Abschnitte sind unter demBegriff „Semaphor“ bekannt. Eingeführt 1965 von E.W. Dijkstra ist ein Semaphor ursprünglich eine Zählsperre S, deren Operationen P(S) =Passieren und V(S) =Verlassen statt LOCK(S) und UNLOCK(S) genannt wurden. Anschaulich hat es den Charakter einer Tür mit Riegel und frei/besetzt-Anzeige.

P wartet bis “Zustand“ den Wert FREI hat, und setzt ihn dann auf BESETZT . Dagegen setzt V einfach den Wert von „Zustand“auf FREI .

Page 26: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Semaphor 2Damit ein Semaphor funktioniert, müssen P und V selbst unteilbare Aktionen/ ununterbrechbare Operationen sein, da sonst der wechselseitige Ausschluss nicht garantiert werden kann.

Zur Unterstützung werden eigene Maschinenbefehle (test-and-set/reset)benutzt, weil diese jeweils ununterbrechbar sind. Semaphore gibt es in verschiedenen Varianten:

• aktives Warten / Blockieren• Zähler / binäre Variable• Initialisierung mit 0 / mit einem Wert k > 0

Der Ablauf : Der erste Prozess, der in den kritischen Bereich kommt, markiert den Eintritt und arbeitet weiter. Versucht ein zweiter Prozess den kritischen Bereichzu betreten, sieht er die Markierung und wartet. Ist der erste Prozess beendet, löscht dieser die Markierung und ermöglicht dem wartenden Prozessden Eintritt.

Page 27: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Binärer Semaphor

Ein binärer Semaphor s besitzt entweder den Wert 0 oder 1. Es gibt zwei Zugriffsfunktionen P(s) und V(s).

Implementation mit aktivem Warten:P(s): while s=0 do { nichts }; s:=0;V(s): s:=1;

Beide Funktionen sind ununterbrechbar implementiert, so dass immernur ein Prozess den Smaphorwert verändern kann. Ferner wird noch eine Funktion zum Erzeugen und Initialisieren eines Semaphors benötigt.

Page 28: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Lösung des Synchronisationsproblems

begin init_semaphor(s,1)

parbegin p0: repeat P(s); kritischer Bereich v(s); until false;

p1: repeat P(s); kritischer Bereich v(s); until false; parend;

end.

Der gegenseitige Ausschluss wird alsonicht mehr im Anwendungsprogrammrealisiert, sondern durch Semaphoren.

P steht daher für: „Das Tor zum kritischenBereich passieren“V für „den kritischen Bereich verlassen“

Page 29: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Semaphor mit passivem Warten

Ein Prozess, der innerhalb von P(s) warten muss, führt kein Polling mehr aus.Er wird mithilfe des Betriebssystems blockiert und wieder geweckt, sobald derkritische Bereich frei ist. Möglicherweise müssen mehrere Prozesse auf einenSemaphor warten. Damit das Warten nicht zum Verhungern führt, wird eineWarteschlange nach dem FIFO-Prinzip eingeführt.

P(s): if s=1 then s:=0 else trage den Prozess in die Warteschlange von s ein und blockiere ihn

V(s): if Queue von s = leer then s:=1 else entferne einen Prozess aus der Queue von s und wecke ihn

Page 30: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Allgemeiner SemaphorEin allgemeiner Semaphor ist eine Erweiterung des binären Typs. DieSemaphorvariable kann einen beliebigen Wert aus der Menge der Natürlichen Zahlen annehmen. Die Zugriffsfunktionen haben folgendes Aussehen:

P(s): if s>0 then s:=s-1 else trage den Prozess in die Warteschlange von s ein und blockiere ihn

V(s): if Queue von s = leer then s:=s+1 else entferne einen Prozess aus der Queue von s und wecke ihn

Mit diesem Semaphor kann ein kritischer Bereich verwaltet werden, in dem sicheine begrenzte Zahl von Prozessen aufhalten kann = Verwalten mehrerergleichartiger Ressourcen

Page 31: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Definition und WertungDefinition:Ein Semaphor besteht aus einer geschützten Variablen s, zwei ZugriffsfunktionenP(s) und V(s), einer Initialisierungsfunktion und einer Warteschlange

Vorteile:• Semaphoren sind universell und für viele Synchronisationsprobleme einfach anwendbar• es wird passiv gewartet und keine CPU-Zeit verschwendet• Warteschlangen nach dem FIFO-Prinzip regeln eine faire Zuteilung

Nachteile:• Wenn P(s) erfolglos ist, muss der Prozess zwingend warten und kann keine anderen Programmteile ausführen• die nicht korrekte Verwendung von V(s) erzeugt Deadlocks.

Die Synchronisation wird also durch ein Hilfsmittel und nicht durch denSchutz eines Codeteils realisiert. Da die kritischen Bereiche über den Codealler Prozesse verteilt sein können, wird ein Überblick erschwert.

Page 32: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Lösung des Erzeuger-/Verbraucher-Problems

1Semaphore mutex = 1 kontrolliert krit. BereichSemaphore empty = N zählt die leeren PuffereinträgeSemaphore full = 0 zählt die belegten Puffereinträge

Erzeuger while (TRUE) { erzeuge_eintrag down (empty) dekrementiere empty down (mutex) Eintritt in den krit. Bereich einfügen_eintrag Eintrag in Puffer einfügen up (mutex) Verlassen des krit. Bereichs up ( full) inkrementieren des Belegt-Zählers }

Verbraucher while (TRUE) { down (full) dekrementiere full down (mutex) Eintritt in den krit. Bereich entnehme_eintrag Eintrag aus Puffer entnehmen up (mutex) Verlassen des krit. Bereichs up ( empty) inkrementieren der leeren Einträge }

Page 33: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Lösung des Erzeuger-/Verbraucher-Problems

2

Die Lösung benutzt drei Semaphoren :1. Einen Semaphor zum Zählen der belegten Puffereinträge2. Einen Semaphor zum Zählen der freien Puffereinträge3. Einen Semaphor, um sicherzustellen, dass Erzeuger und Verbraucher nicht simultan auf den Puffer zugreifen. Dieser Semaphor wird mit Eins initialisiert, um zu gewährleisten, dass sich nur ein Prozess zu einem Zeitpunkt im kritischen Bereich befindet

Der Semaphor mutex wird zur Durchsetzung des wechselseitigen Ausschlussesverwendet, full und empty werden eingesetzt, um bestimmte Ereignisreihen-folgen zuzulassen, also zur Synchronisation

Page 34: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 1

E.W. Dijkstra hat 1965 ein klassisches Beispiel angegeben, das beide Aspekte,Verklemmung, Fairness und Semaphoren demonstriert :

Fünf Philosophen sitzen um einen Tisch. Jeder hat einen Teller mit Spaghettivor sich. Außerdem stehen insgesamt fünf Gabeln zur Verfügung, die anfangszwischen den Tellern liegen.

Jeder Philosoph denkt eine Weile nach, wird dann hungrig und will essen.

Java-Applet von SUN

Essende Philosophen in Berlin

Essende Mönche aus Augsburg 

Page 35: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 2

Damit ein Philosoph essen kann, braucht er die beiden Gabeln links undrechts von seinem Teller.

Er versucht also, diese in beliebiger Reihenfolge aufzunehmen. Hat er beide, isst er eine Weile. Danach legt er beide Gabeln wieder ab.

Das Problem besteht nun darin, ein Programm zu schreiben, dasVerklemmungen und Verhungern vermeidet.

Page 36: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 3

Lösungsidee :

Philosoph while (TRUE) { think () Philosoph denkt take_fork(i) nimm linke Gabel take_fork (i+1 MOD 5) nimm rechte Gabel eat () put_fork (i) lege linke Gabel ab put_fork (i+1 MOD 5) lege rechte Gabel ab

Page 37: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 4

Eine Verklemmung entsteht, wenn zufällig alle Philosophen gleichzeitigihre rechte Gabel aufnehmen.

Andererseits verhungert ein Philosoph, wenn ihm seine Nachbarn immer dieGabeln wegschnappen, wenn er hungrig ist.

Eine scheinbare Lösung des ersten Problems ist es, bei Erhalt einer Gabel zuprüfen, ob die andere frei ist und andernfalls die Gabel wieder hinzulegen. Dies kann aber zu zyklischem Aufnehmen und Ablegen der jeweils rechtenGabel führen, ohne dass jemals gegessen wird - Verhungern

Page 38: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 5

Die nächste Lösungsidee verwendet Sperrsynchronisation zwischen allenPhilosophen über ein binäres Semaphor mutex :

• Wenn Philosoph hungrig wird, ruft er mutex auf. • Hat er die Sperre, führt er den gesamten Zyklus "Gabeln aufnehmen - essen - Gabeln ablegen" unter Ausschluss aller anderen Philosophen aus.

Dies ist eine korrekte Lösung; allerdings ißt nur jeweils ein Philosophobwohl bei fünf Gabeln zwei essen könnten. Die Lösung schränkt damitdie Parallelität ein,

Page 39: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 6

Eine Lösung mit größtmöglicher Parallelität verwendet ein verfeinertesModell :

• Jeder Philosoph hat die möglichen Zustände THINKING, HUNGRY , EATING . • EATING kann er nur erreichen, wenn er HUNGRY ist und seine beiden Nachbarn nicht im Zustand EATING sind. • Die zugehörigen Abfragen müssen unter wechselseitigem Ausschluss erfolgen; hierzu dient ein globales binäres Semaphor mutex .• Jeder Philosoph hat zudem ein eigenes allgemeines Semaphor, mit dem er sich selbst blockiert, wenn er seine Gabeln nicht bekommen konnte. Damit bleibt sein Bedarf angemeldet. Dieses Semaphor wird von einem Nachbarn wieder freigegeben, wenn dieser fertig ist und auch der andere Nachbar gerade nicht ißt.

Page 40: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 7 a

Lösung : N = 5 LEFT = (i-1 MOD N)

RIGHT =( i+1 MOD 5) THINKING = 0, HUNGRY = 1, EATING = 2 semaphor mutex = 1 wechselseitiger Ausschluss semaphor s (N) ein Semaphor für jeden Philosophen

Philosoph while (TRUE) { think () take_forks (i) nimm beide Gabeln oder blockiere eat () put_forks (i) lege beide Gabeln ab

take_forks down (mutex) tritt in krit. Bereich ein state (i) = HUNGRY test (i) versuche beide Gabeln zu erhalten up (mutex) verlasse krit. Bereich down ( s(i)) blockiere, falls Gabeln nicht frei waren

Page 41: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Philosophenproblem 7 b

put_forks down (mutex) tritt in krit. Bereich ein state (i) = THINKING test (LEFT) prüfe, ob linker Nachbar jetzt essen kann test (RIGHT) up (mutex) verlasse krit. Bereich

test if (state (i) == HUNGRY && state (LEFT) != EATING && state (RIGHT) != EATING) state (i) =EATING up ( s(i)) ein Philosoph kann nur in den Zustand EATING gelangen, wenn seine beiden Nachbarn nicht essen, d.h. keine Gabel besitzen. Der Semaphor s blockiert hungrige Philosophen, falls die benötigten Gabeln in Gebrauch sind.

Page 42: Prozesskoordination Prof. Dr. W. Riggert. Ausgangssituation Prozesse müssen häufig untereinander kommunizieren, z.B. Pipes in UNIX. Zwei Prozesse heißen.

Priorität

Höhere Priorität bedeutet Vorrang :

Wird zu einem Zeitpunkt ein Prozess P ausführbereit, der höhere Prioritäthat als der laufende Prozess T , wird T unterbrochen und P ausgeführt (preemptive scheduling).

Hierbei ist darauf zu achten, dass nicht zu viele Prozesse mit der höchstenPriorität versehen werden, da sie sich dann wieder gegenseitig behindern.

Man kann folgende Faustregel für die Prioritätsvergabe aufstellen: Ein dauernd laufender Prozess sollte geringere Priorität haben als einer, der eher seltene Ereignisse behandelt.