diff --git a/09-termin.md b/09-termin.md new file mode 100644 index 0000000..48473c4 --- /dev/null +++ b/09-termin.md @@ -0,0 +1,39 @@ + + +# Termin 9 + +--- + +# Fragen + +--- + +# Links +[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium) +- Aufgaben +- Tutoriumsfolien + * In Präsentationsansicht: [https://wi-pm2-tut.informatik.haw-hamburg.de](https://wi-pm2-tut.informatik.haw-hamburg.de/) + +--- + +# Plan für heute + +Level 7 Themen: + +- Objektorientierter Entwurf +- Nebenläufikeit 1 +- **Nebenläufikeit 2** + +--- + +# Plan + +* 1.7. findet nicht statt, aber es gibt eine Aufzeichnung. +* Prüfungsvorberreitung gibt es in aufgezeichneter Form und eine Referenzimplementation unter [https://git.haw-hamburg.de/pm2-tutorium/code/referenz-loesung-pm2-2019](https://git.haw-hamburg.de/pm2-tutorium/code/referenz-loesung-pm2-2019). +* Fragen gerne auf Teams stellen. Am Montag den 5.7. um 11 Uhr gibt es noch eine Fragestunde, die auch aufgezeichnet wird. diff --git a/nebenlaeufigkeit.md b/nebenlaeufigkeit.md index fe308fa..7fb740a 100644 --- a/nebenlaeufigkeit.md +++ b/nebenlaeufigkeit.md @@ -153,3 +153,102 @@ Ausgangslage: Das Feld `c` hat den Wert `5`. 5) Thread `A`: Den ermittelten Wert in `c` abspeichern. `c` ist jetzt `4`. 6) Thread `B`: Den ermittelten Wert in `c` abspeichern. `c` ist jetzt `4`. +--- + +# Mechanismen zur Synchronisation + +Um das `Lost update problem` zu beheben müssen wir die Threads miteinander synchronisieren. Die Synchronisation kann auf drei verschiedenen Ebenen passieren: + +* Hardware-Ebene +* Betriebssystem-Ebene +* Programiersprachen-Ebene + +--- + +# HW Ebene + +Durch den HW-Befehl `SWAP(a,b)`, welcher unteilbar die Werte von zwei Variablen vertauscht, kann eine Synchronisation mit aktivem Warten durchgeführt werden. + +```java +int c = 1; //gemeinsame Variable +int i = 0; //prozesslokale Variable + +do { + SWAP(c,i) +} while (i == 0) + +// Kritischer Abschnitt + +SWAP(c,i); +``` + +Damit können wir schon eine Synchronisation durchführen. Leider basiert die Lösung aber auf aktivem Warten, was nicht perfomant ist. + +--- + +# Betriebssystem Ebene + +In einem Betriebssystem können noch andere Prozess-Operationen durchgeführt werden. Es gibt Operationen mit denen ein Prozess freiwillig seine Rechenzeit abgeben kann und es können Prozesse aufgeweckt werden die weiterarbeiten können. + +Das Betriebssystem hat dabei verschiedene Strategien nach denen der nächste Prozess ausgewählt werden kann. + +--- + +# Semaphore + +Semaphore bestehen aus eine Zähler und einer Warteschlange. Bei der Initialisierung eines Semaphores übergibt man den Wert des Zählers, die Warteschlange ist zu Beginn leer. + +Auf einem Semaphor können zwei Operationen durchgeführt werden: + + * **P (passieren)**: Der Zähler wird dekrementiert. Ist er positiv, wird der Prozess in den folgenden Abschnitt gelassen. Ist er kleiner als 0 wird der aufrufende Prozess in die Warteschlange eingereiht. + * **V (freigeben)**: Der Zähler wird inkrementiert. Ist der Zähler jetzt größer oder gleich 0 wird ein Prozess aus der Warteschlange aufgeweckt. + +So kann die Vergabe von beschränkten Resourcen geregelt werden. Außerdem kann gegenseitiger Ausschluss sichergestellt werden wenn der Sempaphor einen Anfangszähler von 1 hat. + +--- + +# Monitore + +Monitore sind ein Bestandteil von Programmiersprachen und ermöglichen gegenseitigen Ausschluss. Idee ist es, dass zusammenhängende Daten **einen** Monitor haben. Im Monitor darf dann immer nur ein Prozess aktiv sein. + +In Java besitzt jedes Objekt einen eigenen Monitor. Mit dem Schlüsselwort `synchronized` wird signalisiert, dass ein Block von dem Monitor überwacht werden soll. Ist ein Thread in einem solchen Block sorgt der Monitor dafür, dass kein anderer Thread den Block betritt. + +Diese Art von gegeseitigem Ausschluss ist schnell implementiert, kann aber dazu führen dass mehr synchronisiert wird als nötig. + +--- + +# Monitor Deklaration + +Für eine ganze Methode. + +```java +public synchronized void ausschlussMethode() { + // Kritischer Abschnitt +} +``` + +Für einen Block. + +```java +public void ausschlussBlock() { + synchronized(this) { + // Kritischer Abschnitt + } +} +``` + +--- + +# Benachrichtigung anderer Threads + +Innerhalb eines Monitors können Threads miteinander interagieren. Innerhalb eines Monitors können folgende Methoden genutzt werden: + + * **`wait()`**: Monitor freigeben und in `wait`-Warteschlange warten. + * **`notify()`**: Einen beliebigen Thread in der `wait`-Warteschlange wecken. + * **`notifyAll()`**: Alle Threads in `wait`- Warteschlange wecken. + +--- + +# Komplexität + +Nebenläufigkeit kann unter Umständen sehr kompliziert werden. Deswegen sollte es nur verwendet werden wenn es wirklich nötig ist.