Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

RW-SystemarchitekturKap. 10 1 Kapitel 10 Nebenläufigkeit und wechselseitiger Ausschluss.

Ähnliche Präsentationen


Präsentation zum Thema: "RW-SystemarchitekturKap. 10 1 Kapitel 10 Nebenläufigkeit und wechselseitiger Ausschluss."—  Präsentation transkript:

1 RW-SystemarchitekturKap Kapitel 10 Nebenläufigkeit und wechselseitiger Ausschluss

2 RW-SystemarchitekturKap Überblick Betriebssysteme 6 Einführung 7 Prozesse, Fäden (threads), Scheduling 8. Speicherverwaltung 9 Dateisysteme 10 Nebenläufigkeit und wechselseitiger Ausschluss 10.1 Softwarelösungen für wechselseitigen Ausschluss 10.2 Wechselseitiger Ausschluss in Hardware 10.3 Wechselseitiger Ausschluss ins Betriebssystem integriert 11 Deadlocks 12 historisches 13 aktuelle Forschung

3 RW-SystemarchitekturKap Nebenläufigkeit Größere Softwaresysteme sind häufig realisiert als eine Menge von nebenläufigen Prozessen. Nebenläufigkeit = potentieller Parallelismus –Nebenläufige Prozesses können parallel auf mehreren Prozessoren ausgeführt werden. –Sie können aber auch pseudo-parallel auf einem Prozessor ausgeführt werden. Grundlegende Fragestellungen: –Zugriff auf gemeinsame Ressourcen? –Koordination, Kommunikation Bei Zugriff auf gemeinsame Ressourcen muss häufig exklusiver Zugriff durch wechselseitiger Ausschluss garantiert werden! Hier: –Softwarelösungen –Hardware-Lösungen –Integration ins Betriebssystem

4 RW-SystemarchitekturKap Ein einfaches Beispiel Annahme: 2 Threads führen (u.a.) diesen Code aus. Threads haben einen gemeinsamen Adressraum. ) Variable chin ist eine gemeinsame Ressource! Mögliche Ausführungsreihenfolge: –Thread 1 liest Zeichen, wird unterbrochen ) Thread 2 –Thread 2 führt Prozedur komplett aus. –Thread 1 führt Rest der Prozedur aus. void echo() { chin = getchar(); /* Zeichen einlesen, speichern in Variable chin */ putchar (chin); /* Zeichen ausgeben */ } Problem: Semantik verändert sich mit dem Thread-Schedule! Unterbrechung hat Effekt auf gemeinsame Variable.

5 RW-SystemarchitekturKap Produzenten-Konsumenten-Problem Paradigma für kooperierende Prozesse: Prozess producer produziert Information, welche von einem Prozess consumer konsumiert wird. Zwischen producer und consumer gibt es einen zyklischen Puffer buffer fester Größe. Gemeinsamer Puffer #define BUFFER_SIZE 10 typedef struct {... } item; item buffer[BUFFER_SIZE]; int in = 0; int out = 0;

6 RW-SystemarchitekturKap Beschränkter Puffer – Insert() und Remove() while (true) { /* Produziere ein Element */ while (((in = (in + 1) % BUFFER_SIZE) == out) ; /* do nothing -- no free buffers */ buffer[in] = item; in = (in + 1) % BUFFER SIZE; } while (true) { while (in == out) ; /* tue nichts – nichts im Puffer */ /* entferne ein Element aus Puffer */ item = buffer[out]; out = (out + 1) % BUFFER SIZE; return item; } buffer in out producer consumer

7 RW-SystemarchitekturKap Produzent-Konsument mit beschränktem Puffer – Was geht schief? Geschwindigkeit Produzent > Geschwindigkeit Konsument Pufferinhalte werden überschrieben. Geschwindigkeit Produzent < Geschwindigkeit Konsument Konsument liest leere Pufferfelder Korrektheit hängt von der relativen Geschwindigkeit der beiden Threads zueinander ab – nur korrekt bei gleicher Geschwindigkeit und günstiger Initialisierung.

8 RW-SystemarchitekturKap Beschränkter Puffer – Insert() und Remove() while (true) { /* Produziere ein Element */ while (((in = (in + 1) % BUFFER_SIZE) == out) ; /* do nothing -- no free buffers */ buffer[in] = item; in = (in + 1) % BUFFER SIZE; } while (true) { while (in == out) ; // do nothing -- nothing to consume // remove an item from the buffer item = buffer[out]; out = (out + 1) % BUFFER SIZE; return item; } buffer in out

9 RW-SystemarchitekturKap Nebenläufigkeit Grundlegende Fragen bei Nebenläufigkeit: –Betriebssystem muss Ressourcen der aktiven Prozesse verwalten. –Es muss wechselseitigen Ausschluss bei gemeinsamen Ressourcen garantieren können. –Die Korrektheit des Ergebnisses muss unabhängig von der relativen Ausführungsgeschwindigkeit der einzelnen Prozesse sein. Kontrollprobleme: –Wechselseitiger Ausschluss, d.h. jeweils nur ein Prozess im kritischen Abschnitt (= der Teil des Programms, der auf gemeinsame, exklusive Ressourcen zugreift) –Verhindere Deadlocks (Blockierung aller Prozesse) –Verhindere Livelocks (Prozess nicht blockiert, macht aber keinen Fortschritt).

10 RW-SystemarchitekturKap Anforderungen an wechselseitigen Ausschluss 1.Höchstens ein Prozess im kritischen Abschnitt. 2.Jeder Prozess hält sich nur endliche Zeit im kritischen Abschnitt auf. 3.Wenn ein Prozess in den kritischen Abschnitt will, so muss er nur endliche Zeit darauf warten. 4.Wenn kein Prozess im kritischen Abschnitt ist, so wird ein interessierter Prozess ohne Verzögerung akzeptiert. 5.Alles funktioniert unabhängig von der relativen Ausführungsgeschwindigkeit der Prozesse.

11 RW-SystemarchitekturKap Softwarelösungen für wechselseitigen Ausschluss Hier: –5 verschiedene Lösungsversuche für wechselseitigen Ausschluss –Analyse der einzelnen Lösungen Letzter Versuch entspricht der Lösung von Peterson (1981) Lösung von Peterson ist eine Vereinfachung des Algorithmus von Dekker (Anfang der 60er Jahre).

12 RW-SystemarchitekturKap Versuch 1 Voraussetzung: –2 Prozesse konkurrieren um eine Ressource –Gemeinsame Variable turn besagt, wer dran ist. –turn ist mit beliebigem Wert initialisiert. /* Prozess 0 */ repeat { while (turn 0) tue nichts; /* kritischer Abschnitt */ turn := 1; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ repeat { while (turn 1) tue nichts; /* kritischer Abschnitt */ turn := 0; /* nichtkrit. Abschnitt */ }

13 RW-SystemarchitekturKap Versuch 1: Analyse Vorteil: –Wechselseitiger Ausschluss ist garantiert. Nachteil: –Busy waiting = aktives Warten ( while (turn 0) tue nichts; ) ) Verschwendung von Rechenzeit beim Warten –Nur abwechselnder Zugriff auf kritischen Abschnitt Beispiel für kritische Situation: –Prozess 0 ist schnell, Prozess 1 ist langsam (sehr langer nicht- kritischer Abschnitt) –… –Bedingung 4 ist nicht erfüllt!

14 RW-SystemarchitekturKap Versuch 2 Jetzt 2 gemeinsame Variablen zur Kommunikation: –Prozess 0 schreibt auf ready[0], liest beide –Prozess 1 schreibt auf ready[1], liest beide –Bedeutung von ready[i] = true : Prozess i will in den kritischen Abschnitt –Initialisierung: ready[0] := false; ready[1] := false; /* Prozess 0 */ repeat { while (ready[1] = true) tue nichts; ready[0] := true; /* kritischer Abschnitt */ ready[0] := false; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ repeat { while (ready[0] = true) tue nichts; ready[1] := true; /* kritischer Abschnitt */ ready[1] := false; /* nichtkrit. Abschnitt */ }

15 RW-SystemarchitekturKap Versuch 2: Analyse Vorteil: Auch nicht-alternierender Zugriff auf kritischen Abschnitt Nachteile: –Busy waiting ( while (ready[i] true) tue nichts; ) –Wechselseitiger Ausschluss nicht garantiert!! Beispiel für Fehlersituation : – ready[0] = ready[1] = false –Prozess 0 schließt Schleife ( while (ready[1] true) tue nichts; ) ab, gibt CPU ab –Prozess 1 schließt Schleife ( while (ready[0] true) tue nichts; ) ab –Jetzt können beide Prozesse ungehindert den kritischen Abschnitt betreten: Prozess 1 betritt kritischen Abschnitt, gibt CPU ab Prozess 0 betritt kritischen Abschnitt

16 RW-SystemarchitekturKap Versuch 3 Anforderung des kritischen Abschnittes wird vorgezogen, um das gezeigte Problem zu verhindern: /* Prozess 0 */ repeat { ready[0] := true; while (ready[1] = true) tue nichts; /* kritischer Abschnitt */ ready[0] := false; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ repeat { ready[1] := true; while (ready[0] = true) tue nichts; /* kritischer Abschnitt */ ready[1] := false; /* nichtkrit. Abschnitt */ }

17 RW-SystemarchitekturKap Versuch 3: Analyse Vorteil: –Auch nicht-alternierender Zugriff auf kritischen Abschnitt –Wechselseitiger Ausschluss garantiert! Nachteil: –Busy waiting ( while (ready[i] true) tue nichts; ) Es kann aber trotzdem ein Problem auftreten: – ready[0] = ready[1] = false –Prozess 0 setzt ready[0] := true und gibt CPU ab –Prozess 1 setzt ready[1] := true –Jetzt werden beide Prozesse ihre Schleife while (ready[i] true) tue nichts; nie verlassen! –Eine solche Situation nennt man Livelock.

18 RW-SystemarchitekturKap Wechselseitiger Ausschluss … Ergebnis: –Anforderung zu früh ) Livelock –Anforderung zu spät ) kein wechselseitiger Ausschluss, kritischer Wettlauf (race condition)

19 RW-SystemarchitekturKap Versuch Nichtstun in Schleife wird ersetzt durch zeitweilige Zurücknahme der Anforderung, um es anderen Prozessen zu erlauben, die Ressource zu belegen: /* Prozess 0 */ repeat { ready[0] := true; while (ready[1] = true) { ready[0] := false; /* zufäll.Verzög. */; ready[0] := true; } /* kritischer Abschnitt */ ready[0] := false; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ repeat { ready[1] := true; while (ready[0] = true) { ready[1] := false; /* zufäll.Verzög. */; ready[1] := true; } /* kritischer Abschnitt */ ready[1] := false; /* nichtkrit. Abschnitt */ }

20 RW-SystemarchitekturKap Versuch 4: Analyse Vorteil: –Auch nicht-alternierender Zugriff auf kritischen Abschnitt –Wegen zufälliger Verzögerung nur geringe Wahrscheinlichkeit für Deadlock. Nachteil: –Busy waiting –Deadlock nach wie vor möglich! –Unsaubere Lösung! –Verhalten ist schlecht vorhersagbar –Es gibt Situationen, in denen es nie voran geht oder es für sehr lange Zeit nicht voran geht –Nach Beobachtung eines unerwünschten Verhaltens tritt dieses möglicherweise über sehr lange Zeit nicht mehr auf ) kritische Wettläufe (race condition)!

21 RW-SystemarchitekturKap Versuch 5 3 gemeinsame Variablen: turn, ready[0], ready[1] Initialisierung: ready[0] := false; ready[1] := false; turn beliebig Variable turn bestimmt, welcher Prozess dran ist. /* Prozess 0 */ repeat { ready[0] := true; turn := 1; while (ready[1] = true && turn = 1) tue nichts; /* kritischer Abschnitt */ ready[0] := false; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ repeat { ready[1] := true; turn := 0; while (ready[0] = true && turn = 0) tue nichts; /* kritischer Abschnitt */ ready[1] := false; /* nichtkrit. Abschnitt */ }

22 RW-SystemarchitekturKap Versuch: Analyse (1) Deadlock: –Kein Deadlock möglich wegen Variable turn ! – turn kann nicht gleichzeitig 0 und 1 sein. Wechselseitiger Ausschluss: –Nur einer von beiden interessiert: der andere darf eintreten, –Beide interessiert: der darf eintreten, auf den turn zeigt Nicht-alternierender Zugriff: –Möglich, weil ready[i] = false, wenn Prozess i in nicht-kritischem Abschnitt.

23 RW-SystemarchitekturKap Versuch: Analyse (2) Vorteile: –Nicht-alternierender Zugriff auf den kritischen Abschnitt –Wechselseitiger Ausschluss garantiert –Kein Deadlock Nachteil: –Aktives Warten Versuch 5 entspricht Petersons Algorithmus für wechselseitigen Ausschluss (1981). Verallgemeinerbar auf n Prozesse (wesentlich komplizierter!).

24 RW-SystemarchitekturKap Wechselseitiger Ausschluss in Software – Was haben wir bisher gelernt? Wechselseitiger Ausschluss ist in Software schwer zu realisieren. Alles was einfacher ist als Petersons Algorithmus ist höchstwahrscheinlich falsch. –Beweise des Gegenteils sind durchaus willkommen … Fehler durch kritische Wettläufe, subtile Fehler Formale Beweise sind unabdingbar! Software-Lösungen für wechselseitigen Ausschluss benötigen aktives Warten. Effizientere Lösungen sind möglich durch –Hardware-Unterstützung –Ins Betriebssystem integrierte Lösungen


Herunterladen ppt "RW-SystemarchitekturKap. 10 1 Kapitel 10 Nebenläufigkeit und wechselseitiger Ausschluss."

Ähnliche Präsentationen


Google-Anzeigen