Kapitel 6.1 Nebenläufigkeit und wechselseitiger Ausschluss

Slides:



Advertisements
Ähnliche Präsentationen
Kapitel 11 Deadlocks RW-Systemarchitekur Kap. 11.
Advertisements

10.2 Wechselseitiger Ausschluss in Hardware
Wiederholung Betriebssystem bietet eine Abstraktion der Hardware an:
Beim Start eines Prozesses in Windows NT, 2000 wird a der Programmtext aus der exe-Datei ab der dort angegebenen Adresse gespeichert.
C Tutorium – Semaphoren –
Kapitel 5. Stacks und Queues
Semaphore void Passieren (semaphore &s) { if (s > 0) { s--;
Terminierung und Deadlocks Enkhbat Daginaa Betreuerin Prof. Heike Wehrheim Totale Korrektheit.
Gliederung Motivation / Grundlagen Sortierverfahren
Systeme 1 Kapitel 7.1 Deadlocks WS 2009/10.
Systeme 1 Kapitel 5 Scheduling WS 2009/10.
Systeme 1 Kapitel 7 Deadlocks WS 2009/10.
Kapitel 7.2 Dining philosophers problem
Systeme 1 Kapitel 5.1 Unix Scheduling WS 2009/101.
FH-Hof Deadlocks Richard Göbel. FH-Hof Deadlock - Definition Menge von Prozessen ist an einem Deadlock beteiligt: wenn jeder Prozess in dieser Menge auf.
Java: Dynamische Datentypen
Sortierverfahren Richard Göbel.
Kapitel 10 Nebenläufigkeit und wechselseitiger Ausschluss
Nebenläufige Programmierung
Algorithmentheorie 04 –Hashing
WS Algorithmentheorie 13 - Kürzeste (billigste) Wege Prof. Dr. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (27 – Kürzeste Wege) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (12 – Dynamische Tabellen) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Vorlesung 10 Mutual Exclusion Peter B. Ladkin Sommersemester 2001 Universität Bielefeld Technische Fakultät.
15.1 Synchronisation nebenläufiger Prozesse
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Java Threads Sebastian Werler
Entwicklung verteilter eingebetteter Systeme - Einführung
Prozesskoordination Prof. Dr. W. Riggert.
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Systeme 1 Kapitel 4 Prozesse WS 2009/10.
Effiziente Algorithmen
Eine Implementierung einer effiziente externe geordnete (!) lineare Liste Operationen: Search(x) Insert(x) Delete(x)
Einführung in die Programmierung
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Geoinformation II Vorlesung 10 SS 2000 Quadtrees.
BIT – Schaßan – WS 02/03 Basisinformationstechnologie HK-Medien Teil 1, 11.Sitzung WS 02/03.
Quantum Computing Hartmut Klauck Universität Frankfurt WS 05/
Kapitel 6 Nebenläufigkeit und wechselseitiger Ausschluss
Einführung in die Programmierung
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Parallel Programming Condition Queues
WS 2012/13 Datenbanksysteme Mi 15:15 – 16:45 R Vorlesung #11 Transaktionsverwaltung.
2.4 Rekursion Klassifikation und Beispiele
Prozess-synchronisation
PHP Basic.
Thread Synchronisation in JAVA
Betriebssysteme Übung 2. Tutorium. Task 1 – Locks (1) Wozu Locks? Dienen dazu, exklusiven Zugriff auf eine Ressource sicherzustellen Lock = binäre Semaphore.

Learning By Doing Parallelverarbeitung Multithreading (Nebenläufigkeit) Alte Idee der Parallelverarbeitung statt rein sequentieller Prozesse Parallelverarbeitung.
Vorgeschichte:. Der Prozess X befindet sich in der CPU in Ausführung
Integritätserhaltung und -Überprüfung in deduktiven Datenbanken
Mehrfachausführungen Schleifen in VB 2010 ee. Programmidee: Der Anwender gibt eine Zahl ein, und das Programm gibt die Mehrfachen dieser Zahl aus (das.
Synchronisation paralleler Transaktionen  AIFB SS Sperrverfahren Sperrverfahren (13/18) Behandlung von Konflikten bei der Sperrvergabe.
Autor: Timo Pagel Nutzung: Diese Lernkarten sind für die Nutzung mit OpenCards gedacht Siehe dazu
Dynamische Prioritäten Statische Prozess-Prioritäten sind sinnvoll, falls Prozesse in wenige Klassen einteilbar (3.3.3) Dynamische Prioritäten.
Threads in Java Threads  Sprachumfang von Java Der Java-Standard fordert nur die Unterstützung von Thread-Prioritäten. Es gibt keine Forderung bzgl.:
Parallel Programming Semaphores / Reader - Writer - Lock
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
© 2008 TravelTainment The Amadeus Leisure Group Thread-Programmierung im Qt-Framework Von: Simon Lubberich Erstbetreuer:
Aufgaben Semaphore Übersicht (Dijkstra)
 Präsentation transkript:

Kapitel 6.1 Nebenläufigkeit und wechselseitiger Ausschluss Systeme 1 Kapitel 6.1 Nebenläufigkeit und wechselseitiger Ausschluss WS 2009/10

Letzte Vorlesung Threads Nebenläufigkeit (Threads) „leichtgewichtige Prozesse“ Gemeinsamer Adressraum Nebenläufigkeit (Threads) parallele bzw. pseudo-parallele Ausführung Kontrollprobleme Wechselseitiger Ausschluss Deadlocks Livelocks Anforderungen an wechselseitigen Ausschluss WS 2009/10

Letzte Vorlesung Anforderungen an wechselseitigen Ausschluss Softwarelösungen Versuche 1 - 5 Busy Waiting Wechselseitiger Ausschluss garantiert Nicht-alternierender Zugriff auf kritischen Abschnitt möglich Versuch 1 Versuch 2 Versuch 3 Versuch 4 Versuch 5 WS 2009/10

Wechselseitiger Ausschluss in Hardware Zur Erinnerung Versuch 2 als Softwarelösung Warum scheiterte dieser Versuch? Weil Testen und Setzen von Flags nicht in einem einzigen Schritt durchführbar: Prozesswechsel zwischen Testen und Setzen ist möglich. /* Prozess 0 */ wiederhole { solange (flag[1] = true) tue nichts; flag[0] := true; /* kritischer Abschnitt */ flag[0] := false; /* nichtkrit. Abschnitt */ } /* Prozess 1 */ wiederhole { solange (flag[0] = true) tue nichts; flag[1] := true; /* kritischer Abschnitt */ Flag[1] := false; /* nichtkrit. Abschnitt */ } WS 2009/10

Wechselseitiger Ausschluss in Hardware Neues Konzept: Einführung atomarer Operationen. Hardware garantiert atomare Ausführung. Testen und Setzen zusammen bilden eine atomare Operation: Definiere neuen Befehl TSL: Test and Set Lock. Da TSL ein einziger Befehl ist, kann ein Prozesswechsel nicht zwischen Testen und Setzen erfolgen (nicht “mitten im Befehl”)‏. WS 2009/10

Wechselseitiger Ausschluss in Hardware Befehl TSL RX, LOCK mit Speicheradresse LOCK und Register RX hat folgende Wirkung: RX = Speicher[LOCK]; Speicher[LOCK] := 1 Ein Befehl, d.h. atomare Ausführung. Prozesse, die Zugriff auf den kritischen Abschnitt erhalten wollen, führen folgende Befehle aus: enter_region: TSL, RX, LOCK // kopiere Lock-Variable und setze Lock CMP RX, #0 // War Lock-Variable = 0? (CMP = compare) JNE enter_region // Wenn Lock schon gesetzt war -> Schleife (JNE = jump if not equal)‏ ... // Fortfahren und Betreten des krit. Abschnitts Prozesse, die den kritischen Abschnitt verlassen, führen folgenden Befehl aus: STOREI LOCK, #0 // Speicher[LOCK] := 0 (STOREI = store immediate)‏ WS 2009/10

Wechselseitiger Ausschluss im Betriebssystem Folgerung: Um aktives Warten zu verhindern, muss wechselseitiger Ausschluss ins Betriebssystem integriert werden! Idee: Statt aktiv zu warten, blockiere Prozesse einfach! Neuer Systemaufruf sleep(lock)‏ Nach Verlassen des kritischen Abschnitts weckt der verlassende Prozess einen anderen Prozess auf, der auf Erlaubnis wartet, den kritischen Abschnitt zu betreten (sofern ein solcher Prozess vorhanden ist).‏ Neuer Systemaufruf wakeup(lock)‏ Parameter lock wird nur gebraucht, um Aufrufe für den gleichen kritischen Abschnitt einander zuzuordnen. Eine Warteschlange pro kritischem Abschnitt WS 2009/10

Mutex Mutex = Mutual Exclusion Vor dem Eintritt in einen kritischen Abschnitt wird die Funktion mutex_lock(lock) aufgerufen. testset(lock) führt atomare TSL-Operation aus; liefert true gdw. Lockvariable vorher 0 war. function mutex_lock(lock) { solange (testset(lock) = false) sleep(lock); } return; WS 2009/10

Mutex Nach Verlassen des kritischen Abschnitts wird mutex_unlock(lock) aufgerufen. Es muss eine Warteschlange für Prozesse geben, die auf lock warten. Nach wakeup(lock) wird der erste Prozess in der Queue bereit (aber nicht notwendigerweise aktiv -> Scheduler-Algorithmus!)‏. Die Variable lock heißt Mutexvariable bzw. kurz Mutex. function mutex_unlock(lock) { unset(lock); // lock wird freigegeben wakeup(lock); return; } WS 2009/10

Das Produzenten-Konsumenten Problem Typisches Problem bei nebenläufigen Prozessen: Gemeinsamer Puffer Einige Prozesse schreiben in den Puffer (“Produzenten”) Einige Prozesse lesen aus dem Puffer (“Konsumenten”)‏ Prozedur insert_item schreibt Objekt in Puffer. Prozedur remove_item entfernt Objekt aus Puffer. Puffergröße ist beschränkt und Puffer kann leer sein. Wenn Puffer voll ist, dann sollten Produzenten nicht einfügen. Aus Effizienzgründen: Blockieren der Produzenten, die einfügen wollen. Wenn Puffer leer ist, sollten Konsumenten nichts entfernen. Aus Effizienzgründen: Blockieren der Konsumenten, die entfernen wollen. WS 2009/10

Das Produzenten-Konsumenten Problem Lösungsansatz: Gemeinsame Variable count für die Anzahl der Elemente im Puffer Initialer Wert 0 sleep() und wakeup()‏ Anfangs schlafen die Konsumenten (Puffer ist leer).‏ WS 2009/10

Das Produzenten-Konsumenten Problem Prozedur producer { ... wiederhole item = produce_item(); //produziere nächstes Objekt wenn (count = MAX_BUFFER) //schlafe, wenn Puffer sleep(producer); //voll insert_item(item) // Einfügen in Puffer count = count + 1; wenn (count = 1) // wenn Puffer vorher leer: wakeup(consumer); // wecke Konsumenten } WS 2009/10

Das Produzenten-Konsumenten Problem Prozedur consumer { ... wiederhole wenn (count = 0) // schlafe, wenn Puffer Sleep(consumer); // leer item = remove_item(); // Entferne aus Puffer count = count -1; wenn (count = MAX_BUFFER – 1) // wenn Puffer voll wakeup(producer); // wecke Produzenten consume_item(item); // konsumiere Objekt } Ist diese Lösung korrekt??? WS 2009/10

Das Produzenten-Konsumenten Problem Mögliche Probleme: Zwei Konsumenten: 1 Element im Puffer Konsument 1 entnimmt Element und wird unterbrochen bevor er count auf 0 setzen kann. Konsument 2 wird aktiv aber der Puffer ist leer! (count immer noch 1) Fehler! Zwei Konsumenten: Puffer ist voll. count == MAX_BUFFER Konsument 1 entnimmt Element und führt count = count–1; aus und wird dann unterbrochen (count == MAX_BUFFER-1)‏. Konsument 2 wird aktiv, entnimmt ein Element und reduziert count. Problem: Produzent wird nie mehr geweckt, da Bedingung wenn (count = MAX_BUFFER – 1)‏ nie mehr erfüllt wird! WS 2009/10

Das Produzenten-Konsumenten Problem Ein Produzent und ein Konsument Konsument gibt Prozessor ab nach wenn(count = 0)‏ wenn Puffer leer ist Dann fügt der Produzent ein Objekt ein, count = 1. Aufwecken des Konsumenten geht verloren, da er noch gar nicht schläft. Nach nächstem Prozesswechsel: Konsument schläft für immer. Wenn Puffer voll wird, schläft auch der Produzent für immer. Deadlock Problem: wenn (count = 0) sleep(consumer)‏ ist keine atomare Operation! WS 2009/10

Das Produzenten-Konsumenten Problem Die elegante Lösung des Produzenten-Konsumenten Problems ist die Nutzung eines Semaphor. Dijkstra (1965)‏ Entwickelt zur Synchronisation von Prozessen. Konzept: Integer-Variable mit drei Operationen: Initialisierung mit nicht-negativen Wert down() Operation up() Operation WS 2009/10

Wechselseitiger Ausschluss mit Semaphoren Voraussetzungen: Es existiert ein Semaphor s. countS ist auf 1 initialisiert. n Prozesse sind gestartet, konkurrieren um kritischen Abschnitt. /* Prozess i */ wiederhole { down(s); /* kritischer Abschnitt */ up(s); /* nichtkritischer Abschnitt */ } WS 2009/10

Wechselseitiger Ausschluss mit Semaphoren Beispiel: Semaphor wird mit 1 initialisiert. Prozess 1 geht in kritischen Abschnitt: down(s) -> Semaphor-Zähler wird 0 Prozess 2 will in den kritischen Abschnitt: down(s) -> Semaphor-Zähler wird -1 Prozess 2 wird blockiert und in die Warteschlange eingefügt. Prozess 3 will in den kritischen Abschnitt: down(s) -> Semaphor-Zähler wird -2 Prozess 3 wird blockiert und in die Warteschlange eingefügt. Prozess 1 verlässt kritischen Abschnitt: up(s) -> Semaphor-Zähler wird -1 Zähler <= 0, d.h. ein Prozess wird der Warteschlange entnommen und wird bereit. WS 2009/10

Wechselseitiger Ausschluss mit Semaphoren Auf 1 initialisierte Semaphore heißen binäre Semaphore. Behandlung mehrfach nutzbarer Ressourcen (m-fach) ist möglich: durch Initialisierung countS = m. Interpretation von counts: Falls countS ≥ 0: countS gibt die Anzahl der Prozesse an, die down(s) ausführen können ohne zu blockieren (wenn nicht zwischenzeitlich up(s) ausgeführt wird). Falls countS < 0: |countS| ist die Anzahl der wartenden Prozesse in queueS. WS 2009/10

Das Produzenten-Konsumenten Problem mit Semaphoren semaphore mutex; countmutex = 1; // mutex für kritische Abschnitte semaphore empty; countempty = MAX_BUFFER; // zählt freie Plätze semaphore full; countfull = 0; // zählt belegte Plätze Prozedur producer { ... wiederhole item = produce_item(); //produziere nächstes Objekt down(empty); down(mutex); insert_item(item); // Einfügen in Puffer up(mutex); up(full); } WS 2009/10

Das Produzenten-Konsumenten Problem mit Semaphoren Prozedur consumer { ... wiederhole down(full); down(mutex); item = remove_item(); // Entferne aus Puffer up(mutex); up(empty); consume_item(item); // konsumiere Objekt } Frage: Funktioniert das immer noch, wenn in Prozedur consumer up(mutex) und up(empty) vertauscht werden? down(full) und down(mutex) vertauscht werden? WS 2009/10

Das Produzenten-Konsumenten Problem mit Semaphoren Frage: Funktioniert das immer noch, wenn in Prozedur consumer up(mutex) und up(empty) vertauscht werden? down(full) und down(mutex) vertauscht werden? Angenommen der Puffer ist leer: down(mutex), down(full)‏ Konsument blockiert, da es keine „vollen Plätze“ gibt. Produzenten können aber nicht den Puffer füllen, da sie alle bei down(mutex) hängen bleiben. Irgendwann schlafen alle -> Deadlock! WS 2009/10

Implementierung von Semaphoren: Versuch 1 down(semaphore s) { mutex_lock(lockS); countS = countS - 1; wenn (countS < 0) setze diesen Prozess in queueS; blockiere den Prozess und führe unmittelbar vor Abgabe des Prozessors noch mutex_unlock(lockS) aus } sonst mutex_unlock(lockS); up(semaphore s)‏ { mutex_lock(lockS); countS = countS + 1; if (countS <= 0)‏ entferne einen Prozess P aus queueS; Schreibe Prozess P in Liste der bereiten Prozesse } mutex_unlock(lockS); k.A. k.A. WS 2009/10

Implementierung von Semaphoren: Versuch 1 Analyse: down und up sind nicht wirklich atomar, aber trotzdem stören sich verschiedene Aufrufe von down und up nicht aufgrund des Mutex. Zumindest für binäre Semaphore ist Verwendung von Mutexen in Semaphoraufrufen etwas aufwändig, weil Mutexe alleine schon reichen, um wechselseitigen Ausschluss zu garantieren! Zwei Queues: Liste von Prozessen, die auf Freigabe des Mutex warten. Liste von Prozessen, die auf Erhöhung der Semaphor-Variable warten. WS 2009/10

Implementierung von Semaphoren: Versuch 2 down(semaphore s) { solange (testset(lockS) = false)‏ tue nichts; countS = countS - 1; wenn (countS < 0) setze diesen Prozess in queueS; blockiere den Prozess und führe unmittelbar vor Abgabe des Prozessors noch lockS = 0 aus } sonst lockS = 0 up(semaphore s)‏ { solange (testset(lockS) = false)‏ tue nichts; countS = countS + 1; if (countS <= 0)‏ entferne einen Prozess P aus queueS; Schreibe Prozess P in Liste der bereiten Prozesse } lockS = 0; k.A. k.A. WS 2009/10

Implementierung von Semaphoren: Versuch 2 Analyse: aktives Warten (solange(...) tue nichts;)! nicht so gravierend: beschränkt auf up und down up und down sind relativ kurz down und up sind nicht wirklich atomar, aber trotzdem stören sich verschiedene Aufrufe von down und up nicht aufgrund des busy waitings. Semaphoren blockieren Prozesse -> keine CPU-Zeit für wartende Prozesse Unterbinden von Unterbrechungen nicht nötig. Implementierung auch für Multiprozessoren geeignet. Für Benutzer sind nur abstrakte Semaphoren sichtbar, keine Implementierungsdetails. WS 2009/10

Subtile Fehler möglich, formale Beweise nötig. Zusammenfassung CPU (einzelne CPU oder Multiprozessor) wird von mehreren Prozessen geteilt. Verwaltung gemeinsamer Ressourcen bei Multiprogramming ist nicht trivial. Subtile Fehler möglich, formale Beweise nötig. Konzepte für wechselseitigen Ausschluss, Produzenten-Konsumenten Problem. WS 2009/10