Add Nebenläufigkeit
This commit is contained in:
parent
f6d3032e74
commit
7c893cf79c
|
@ -0,0 +1,39 @@
|
|||
<!--
|
||||
title: Termin 9
|
||||
description: Folien für den ersten Termin in Programmieren 2
|
||||
url: https://git.haw-hamburg.de/pm2-tutorium/slides
|
||||
header: Programmieren 2 **Tutorium**
|
||||
footer: Henri Burau
|
||||
-->
|
||||
|
||||
# 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.
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue