Multithreading fix

This commit is contained in:
WieErWill 2021-04-09 10:02:33 +02:00
parent bd21045741
commit 3cd4b5951e
2 changed files with 153 additions and 224 deletions

Binary file not shown.

View File

@ -2601,17 +2601,17 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\begin{itemize*} \begin{itemize*}
\item Rekursive Funktion von g \item Rekursive Funktion von g
\begin{itemize*} \begin{itemize*}
\item $g = \lambda n.…g…n…$ Rumpf verwendet g \item $g = \lambda n...g...n...$ Rumpf verwendet g
\end{itemize*} \end{itemize*}
\item Daraus gewinnt man das Funktional \item Daraus gewinnt man das Funktional
\begin{itemize*} \begin{itemize*}
\item $G = \lambda g.\lambda n.…g…n…$ \item $G = \lambda g.\lambda n...g...n...$
\end{itemize*} \end{itemize*}
\item Falls G einen Fixpunkt g* hat, d.h. $G(g*) = g*$, so \item Falls G einen Fixpunkt g* hat, d.h. $G(g*) = g*$, so
\begin{itemize*} \begin{itemize*}
\item $g* = G(g*) = \lambda n.…g*n$ \item $g* = G(g*) = \lambda n...g*...n$
\end{itemize*} \end{itemize*}
\item Vergleiche: $g = \lambda n.…g…n…$ \item Vergleiche: $g = \lambda n...g...n...$
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
Rekursive Definition $\Leftrightarrow$ Fixpunkt des Funktionals Rekursive Definition $\Leftrightarrow$ Fixpunkt des Funktionals
@ -2647,7 +2647,7 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\begin{itemize*} \begin{itemize*}
\item Anfangsfunktionen: \item Anfangsfunktionen:
\begin{itemize*} \begin{itemize*}
\item Projektion: $U_i^k (n_1,n_2,,n_k) = n_i$ für $1<=i<=k$ \item Projektion: $U_i^k (n_1,n_2,...,n_k) = n_i$ für $1<=i<=k$
\item Nullfunktion: $Z(n) = 0$ \item Nullfunktion: $Z(n) = 0$
\item Nachfolger: $S(n) = n+1$ \item Nachfolger: $S(n) = n+1$
\end{itemize*} \end{itemize*}
@ -2656,15 +2656,15 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\item Für eine Relation $P(m)$ bezeichne $\mu m[P(m)]$ die kleinste Zahl m sodass P(m) gilt. \item Für eine Relation $P(m)$ bezeichne $\mu m[P(m)]$ die kleinste Zahl m sodass P(m) gilt.
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\item Bemerkung: im Folgenden notieren wir $n_1,n_2,,n_k$ kurz als $\overline{n_k}$ \item Bemerkung: im Folgenden notieren wir $n_1,n_2,...,n_k$ kurz als $\overline{n_k}$
\item Eine numerische Funktion ist Lambda-definierbar, wenn es einen Kombinator M gibt, sodass $M\overline{n_k} = f(\overline{n_k})$ \item Eine numerische Funktion ist Lambda-definierbar, wenn es einen Kombinator M gibt, sodass $M\overline{n_k} = f(\overline{n_k})$
\end{itemize*} \end{itemize*}
\begin{itemize*} \begin{itemize*}
\item Im folgenden sei C eine Klasse von numerischen Funktionen, und es gelte $g,h,h_1,h_2,,h_m \in C$ \item Im folgenden sei C eine Klasse von numerischen Funktionen, und es gelte $g,h,h_1,h_2,...,h_m \in C$
\item Wir definieren nun die folgenden Eigenschaften: \item Wir definieren nun die folgenden Eigenschaften:
\begin{itemize*} \begin{itemize*}
\item C ist \color{blue} abgeschlossen unter Komposition\color{black}, wenn für jede Funktion f, die über $f(\overline{n_k}):= g(h_1(\overline{n_k}),,h_m(\overline{n_k}))$ definiert ist, gilt $f \in C$ \item C ist \color{blue} abgeschlossen unter Komposition\color{black}, wenn für jede Funktion f, die über $f(\overline{n_k}):= g(h_1(\overline{n_k}),...,h_m(\overline{n_k}))$ definiert ist, gilt $f \in C$
\item C ist \color{blue} abgeschlossen unter primitiver Rekursion\color{black}, wenn für jede Funktion f, die über \item C ist \color{blue} abgeschlossen unter primitiver Rekursion\color{black}, wenn für jede Funktion f, die über
$$f(0,\overline{n_k}) = g(\overline{n_k})$$ $$f(0,\overline{n_k}) = g(\overline{n_k})$$
$$f(j+1, \overline{n_k}) = h(f(j,\overline{n_k}),j,\overline{n_k})$$ $$f(j+1, \overline{n_k}) = h(f(j,\overline{n_k}),j,\overline{n_k})$$
@ -2683,7 +2683,7 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\item \color{blue} Lemma 1: Die Anfangsfunktionen sind Lambda-definierbar \color{black} \item \color{blue} Lemma 1: Die Anfangsfunktionen sind Lambda-definierbar \color{black}
\item Beweis: \item Beweis:
\begin{itemize*} \begin{itemize*}
\item $U_i^k = \lambda x_1 x_2 x_k.x_i$ \item $U_i^k = \lambda x_1 x_2 ... x_k.x_i$
\item $S = \lambda n.\lambda s. \lambda z.s(nsz)$ (siehe succ bei Churchzahlen) \item $S = \lambda n.\lambda s. \lambda z.s(nsz)$ (siehe succ bei Churchzahlen)
\item $Z = \lambda fx.x$ (siehe $c_0$ bei Churchzahlen) \item $Z = \lambda fx.x$ (siehe $c_0$ bei Churchzahlen)
\end{itemize*} \end{itemize*}
@ -2799,7 +2799,7 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\item Hierbei ist es insbesondere von Interesse, wie Parameter gehandhabt werden, deren Werte undefiniert sind (z.B. 1/0)\newline \item Hierbei ist es insbesondere von Interesse, wie Parameter gehandhabt werden, deren Werte undefiniert sind (z.B. 1/0)\newline
\colorbox{lightgray}{ \colorbox{lightgray}{
\begin{minipage}[h]{1.0\linewidth} \begin{minipage}[h]{1.0\linewidth}
Wir definieren zunächst den zentralen begriff "strikt": \newline Eine n-stellige Funktion heißt strikt im k-ten Argument $(1<=k<=n)$, wenn gilt: $f(x_1,x_2,,x_{k-1},\bot,x_{k+1},,x_n)=\bot$ Wir definieren zunächst den zentralen begriff "strikt": \newline Eine n-stellige Funktion heißt strikt im k-ten Argument $(1<=k<=n)$, wenn gilt: $f(x_1,x_2,...,x_{k-1},\bot,x_{k+1},...,x_n)=\bot$
\end{minipage}} \end{minipage}}
\item Ein undefiniertes Argument führt hier zu einem undefinierten Resultat \item Ein undefiniertes Argument führt hier zu einem undefinierten Resultat
\item Grundsätzlich kann man die Auswertungsstrategien von Programmiersprachen in strikte und nicht-strikte Strategien einteilen; sehr gebräuchlich sind dabei insbesondere: \item Grundsätzlich kann man die Auswertungsstrategien von Programmiersprachen in strikte und nicht-strikte Strategien einteilen; sehr gebräuchlich sind dabei insbesondere:
@ -2849,7 +2849,7 @@ $\lambda x.xx$ wendet sein Argument auf das Argument selbst an $\Rightarrow$ dad
\item Die folgenden Gleichungen definieren eine nicht-strikte Multiplikation $\otimes$ auf der Basis der Multiplikation · für Zahlen: \item Die folgenden Gleichungen definieren eine nicht-strikte Multiplikation $\otimes$ auf der Basis der Multiplikation · für Zahlen:
$$0 \otimes y = 0$$ $$0 \otimes y = 0$$
$$x \otimes 0 = 0$$ $$x \otimes 0 = 0$$
$$x \otimes y = x · y$$ $$x \otimes y = x * y$$
\item Wenn ein Arguemnt undefiniert ist, dann liefert $\otimes$ ein Ergebnis, sofern das andere Argument zu 0 evaluiert wird ($\rightarrow fak(-1) \otimes (fak(3)-6)$) \item Wenn ein Arguemnt undefiniert ist, dann liefert $\otimes$ ein Ergebnis, sofern das andere Argument zu 0 evaluiert wird ($\rightarrow fak(-1) \otimes (fak(3)-6)$)
\item Implementiert werden kann die Funktion nur durch eine Art von paralleler Auswertung mit Abbruch der anderen Berechnung sobald 0 als Resultat berechnet und zurückgegeben wurde \item Implementiert werden kann die Funktion nur durch eine Art von paralleler Auswertung mit Abbruch der anderen Berechnung sobald 0 als Resultat berechnet und zurückgegeben wurde
\end{itemize*} \end{itemize*}
@ -2899,10 +2899,10 @@ $\Rightarrow$ call-by-name, call-by-value
\subsubitem $\Rightarrow (\lambda \color{blue}y\color{black}(\lambda x. \color{blue}y\color{black}(\lambda z.z)x))\color{red}(\lambda y.y)\color{black}$ \subsubitem $\Rightarrow (\lambda \color{blue}y\color{black}(\lambda x. \color{blue}y\color{black}(\lambda z.z)x))\color{red}(\lambda y.y)\color{black}$
\subsubitem $\Rightarrow (\lambda x.(\lambda y.y(\lambda z.z)x)) \nRightarrow$ \subsubitem $\Rightarrow (\lambda x.(\lambda y.y(\lambda z.z)x)) \nRightarrow$
\item Intuition: Argumente vor Funktionsaufruf auswerten \item Intuition: Argumente vor Funktionsaufruf auswerten
\item Auswertungsstrategie vieler Sprachen: Java, C, Scheme, ML, \item Auswertungsstrategie vieler Sprachen: Java, C, Scheme, ML, ...
\item Arithmetik in Haskell: Auswertung by-value \item Arithmetik in Haskell: Auswertung by-value
\item $prodOf(x) = y * prodOf x$ \item $prodOf(x) = y * prodOf x$
\item $3 * prodOf 3 \Rightarrow 3 * (3 * prodOf 3) \Rightarrow$ \item $3 * prodOf 3 \Rightarrow 3 * (3 * prodOf 3) \Rightarrow$ ...
\item $((div \space1 \space 0) * 6) * 0 \Rightarrow \bot$ \item $((div \space1 \space 0) * 6) * 0 \Rightarrow \bot$
\item $((div \space2 \space 2) * 6) * 0 \Rightarrow ((1 * 6) * 0) \Rightarrow 6 * 0\Rightarrow 0 \nRightarrow$ \item $((div \space2 \space 2) * 6) * 0 \Rightarrow ((1 * 6) * 0) \Rightarrow 6 * 0\Rightarrow 0 \nRightarrow$
\end{itemize*} \end{itemize*}
@ -2974,7 +2974,7 @@ $\Rightarrow$ call-by-name, call-by-value
\subsubsection{The free launch is over} \subsubsection{The free launch is over}
Taktfrequenz wächst nur noch langsam Taktfrequenz wächst nur noch langsam
\begin{itemize*} \begin{itemize*}
\item Physikalische Gründe: Wärmeentwicklung, Energiebedarf, Kriechströme, \item Physikalische Gründe: Wärmeentwicklung, Energiebedarf, Kriechströme,...
\end{itemize*} \end{itemize*}
Auswege Auswege
\begin{itemize*} \begin{itemize*}
@ -3080,8 +3080,8 @@ $\Rightarrow$ call-by-name, call-by-value
\begin{itemize*} \begin{itemize*}
\item Maße für Laufzeitgewinn durch Parallelisierung \item Maße für Laufzeitgewinn durch Parallelisierung
\item $T_n$ = Laufzeit des Programms mit n Prozessoren/Kernen \item $T_n$ = Laufzeit des Programms mit n Prozessoren/Kernen
\item Speedup $Speedup = {{T_1} \over {T_n}}$ \item Speedup $Speedup = \frac{T_1}{T_n}$
\item Effizienz $Effizienz = {Speedup \over n}$ \item Effizienz $Effizienz = \frac{Speedup}{n}$
\end{itemize*} \end{itemize*}
\subsubsection{Amdahlsches Gesetz} \subsubsection{Amdahlsches Gesetz}
@ -3091,7 +3091,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item s = serieller Anteil \item s = serieller Anteil
\item n Prozessoren \item n Prozessoren
\item $p+s = 1$ \item $p+s = 1$
\item Maximaler Speedup $Speedup_{max} = {T_1 \over T_n} = {{s+p}\over{s+{p \over n}}} = {1 \over {s+{p \over n}}} = \frac{1}{s+\frac{p}{n}}$ \item Maximaler Speedup $Speedup_{max} = \frac{T_1}{T_n} = {\frac{s+p}{s+ \frac{p}{n}}} = \frac{1}{s+\frac{p}{n}}$
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.35\linewidth]{Assets/Programmierparadigmen-parallelisierung} \includegraphics[width=0.35\linewidth]{Assets/Programmierparadigmen-parallelisierung}
@ -3177,7 +3177,7 @@ $\Rightarrow$ call-by-name, call-by-value
\includegraphics[width=0.9\linewidth]{Assets/Programmierparadigmen-Datenparallelität} \includegraphics[width=0.9\linewidth]{Assets/Programmierparadigmen-Datenparallelität}
\caption{Datenparallelität} \caption{Datenparallelität}
\begin{itemize*} \begin{itemize*}
\item homogene Datenmenge: Felder, Listen, Dokumentenmenge, \item homogene Datenmenge: Felder, Listen, Dokumentenmenge,...
\item Verteilung der Daten \item Verteilung der Daten
\item alle Prozessoren führen gleiches Programm auf jeweils eigenen Daten aus \item alle Prozessoren führen gleiches Programm auf jeweils eigenen Daten aus
\item Beispiel: Matrixaddition S = A + B \item Beispiel: Matrixaddition S = A + B
@ -3216,7 +3216,7 @@ $\Rightarrow$ call-by-name, call-by-value
\begin{itemize*} \begin{itemize*}
\item Problemzerlegung \item Problemzerlegung
\item Synchronisation \item Synchronisation
\item \item ...
\end{itemize*} \end{itemize*}
\item im Weiteren: konkrete Methoden und Techniken in Erlang und C++ \item im Weiteren: konkrete Methoden und Techniken in Erlang und C++
\end{itemize*} \end{itemize*}
@ -3228,9 +3228,9 @@ $\Rightarrow$ call-by-name, call-by-value
\item SMP-Support (Symmetric Multi Processing) \item SMP-Support (Symmetric Multi Processing)
\item Ziele für effiziente Parallelisierung \item Ziele für effiziente Parallelisierung
\begin{itemize*} \begin{itemize*}
\item Problem in viele Prozesse zerlegen (aber nicht zu viele ) \item Problem in viele Prozesse zerlegen (aber nicht zu viele ...)
\item Seiteneffekte vermeiden (würde Synchronisation erfordern ) \item Seiteneffekte vermeiden (würde Synchronisation erfordern ...)
\item Sequentiellen Flaschenhals vermeiden (Zugriff auf gemeinsame Ressourcen: IO, Registrierung von Prozessen, ) -> Small Messages, Big Computation! \item Sequentiellen Flaschenhals vermeiden (Zugriff auf gemeinsame Ressourcen: IO, Registrierung von Prozessen, ...) -> Small Messages, Big Computation!
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
@ -3434,7 +3434,7 @@ $\Rightarrow$ call-by-name, call-by-value
\subsubsection{Datenparallelität: Das Map-Reduce-Paradigma} \subsubsection{Datenparallelität: Das Map-Reduce-Paradigma}
\begin{itemize*} \begin{itemize*}
\item Parallelisierungsmuster inspiriert von Konzepten funktionaler Programmiersprachen (map,reduce/fold) \item Parallelisierungsmuster inspiriert von Konzepten funktionaler Programmiersprachen (map,reduce/fold)
\item Basis von Big-Data-plattformen wie Hadoop, Spark, \item Basis von Big-Data-plattformen wie Hadoop, Spark,...
\item Grundidee: \item Grundidee:
\begin{itemize*} \begin{itemize*}
\item map(F, Seq) ? wende Funktion F (als Argument übergeben) auf alle Elemente einer Folge Seq an, \item map(F, Seq) ? wende Funktion F (als Argument übergeben) auf alle Elemente einer Folge Seq an,
@ -3496,7 +3496,7 @@ $\Rightarrow$ call-by-name, call-by-value
\begin{itemize*} \begin{itemize*}
\item Prozess für das Sortieren der einen Hälfte starten \item Prozess für das Sortieren der einen Hälfte starten
\item Elternprozess kann andere Hälfte sortieren \item Elternprozess kann andere Hälfte sortieren
\item rekursive Zerlegung \item rekursive Zerlegung...
\end{itemize*} \end{itemize*}
\subsubsection{Parallel Quicksort} \subsubsection{Parallel Quicksort}
@ -3695,7 +3695,7 @@ $\Rightarrow$ call-by-name, call-by-value
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-20} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-20}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
\item Nutzung für Implementierung von Threadpools, Task Libraries, \item Nutzung für Implementierung von Threadpools, Task Libraries, ...
\end{itemize*} \end{itemize*}
\subsubsection{Probleme nebenläufiger Ausführung} \subsubsection{Probleme nebenläufiger Ausführung}
@ -3851,7 +3851,7 @@ $\Rightarrow$ call-by-name, call-by-value
\begin{itemize*} \begin{itemize*}
\item Jeder greift die linke Gabel \item Jeder greift die linke Gabel
\item und wartet auf die rechte Gabel \item und wartet auf die rechte Gabel
\item … und wartet … \item ... und wartet ...
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.3\linewidth]{Assets/Programmierparadigmen-philosophen} \includegraphics[width=0.3\linewidth]{Assets/Programmierparadigmen-philosophen}
@ -3883,37 +3883,37 @@ $\Rightarrow$ call-by-name, call-by-value
\paragraph{Gabeln und Spaghetti-Teller} \paragraph{Gabeln und Spaghetti-Teller}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-073} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-25}
\end{center} \end{center}
\paragraph{Die Philosophen-Klasse} \paragraph{Die Philosophen-Klasse}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-074} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-26}
\end{center} \end{center}
\paragraph{Die Philosophen-Klasse: Hilfsmethoden} \paragraph{Die Philosophen-Klasse: Hilfsmethoden}
Textausgabe erfordert synchronisierten Zugriff auf cout über globalen Mutex Textausgabe erfordert synchronisierten Zugriff auf cout über globalen Mutex
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-075} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-27}
\end{center} \end{center}
Hilfsmethode für zufällige Wartezeit in Millisekunden Hilfsmethode für zufällige Wartezeit in Millisekunden
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-076} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-28}
\end{center} \end{center}
\paragraph{Die Philosophen-Klasse: Essen} \paragraph{Die Philosophen-Klasse: Essen}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-077} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-29}
\end{center} \end{center}
\paragraph{Die Philosophen-Klasse: Denken} \paragraph{Die Philosophen-Klasse: Denken}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-078} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-30}
\end{center} \end{center}
\paragraph{Das Leben eines Philosophen} \paragraph{Das Leben eines Philosophen}
@ -3922,13 +3922,13 @@ $\Rightarrow$ call-by-name, call-by-value
\item Zur Erinnerung: überladener ()-Operator eines Objekts definiert auszuführende Funktion eines Threads \item Zur Erinnerung: überladener ()-Operator eines Objekts definiert auszuführende Funktion eines Threads
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-079} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-31}
\end{center} \end{center}
\paragraph{Das Dinner: Initialisierung} \paragraph{Das Dinner: Initialisierung}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-080} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-32}
\end{center} \end{center}
\paragraph{Das Dinner beginnt} \paragraph{Das Dinner beginnt}
@ -3938,7 +3938,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item Philosophen-Threads arbeiten ihre operator()()-Methode ab \item Philosophen-Threads arbeiten ihre operator()()-Methode ab
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-081} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-33}
\end{center} \end{center}
\paragraph{Fazit} \paragraph{Fazit}
@ -3965,7 +3965,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item typischer Anwendungsfall: Warten auf Ereignis / Setzen eines Flags \item typischer Anwendungsfall: Warten auf Ereignis / Setzen eines Flags
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-082} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-34}
\end{center} \end{center}
\subsubsection{Bedingungsvariablen} \subsubsection{Bedingungsvariablen}
@ -3975,10 +3975,8 @@ $\Rightarrow$ call-by-name, call-by-value
\item notwendig: synchronisierter Zugriff über Mutex \item notwendig: synchronisierter Zugriff über Mutex
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-083} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-35}
\end{center} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-36}
\begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-084}
\end{center} \end{center}
\subsubsection{Thread-sichere Datenstrukturen} \subsubsection{Thread-sichere Datenstrukturen}
@ -4008,7 +4006,6 @@ $\Rightarrow$ call-by-name, call-by-value
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\subsubsection{Anforderungen} \subsubsection{Anforderungen}
\begin{itemize*} \begin{itemize*}
\item mehrere Threads können gleichzeitig auf die Datenstruktur zugreifen \item mehrere Threads können gleichzeitig auf die Datenstruktur zugreifen
@ -4020,7 +4017,7 @@ $\Rightarrow$ call-by-name, call-by-value
\subsubsection{Thread-sichere Queue} \subsubsection{Thread-sichere Queue}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-085} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-37}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
\item Zeilen 1,2,6: Kapselung der std::queue-Klasse \item Zeilen 1,2,6: Kapselung der std::queue-Klasse
@ -4031,7 +4028,7 @@ $\Rightarrow$ call-by-name, call-by-value
\paragraph{Thread-sichere Queue: Methode push} \paragraph{Thread-sichere Queue: Methode push}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-086} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-38}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
\item Zeile 2: Lock Guard sichert exklusiven Zugriff \item Zeile 2: Lock Guard sichert exklusiven Zugriff
@ -4042,7 +4039,7 @@ $\Rightarrow$ call-by-name, call-by-value
\paragraph{Thread-sichere Queue: Methode waiting\_pop} \paragraph{Thread-sichere Queue: Methode waiting\_pop}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-087} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-39}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
\item Zeile 2: Lock Guard sichert exklusiven Zugriff \item Zeile 2: Lock Guard sichert exklusiven Zugriff
@ -4056,7 +4053,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item std::async() - asynchrones Starten eines Tasks \item std::async() - asynchrones Starten eines Tasks
\begin{center} \begin{center}
\centering \centering
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-088} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-40}
\end{center} \end{center}
\item std::promise - erlaubt Wert zu setzen, wenn der aktuelle Thread beendet ist, of in Kombination mit std::future eingesetzt \item std::promise - erlaubt Wert zu setzen, wenn der aktuelle Thread beendet ist, of in Kombination mit std::future eingesetzt
\item future = Ergbenisobjekt, promise = Ergebnisproduzent \item future = Ergbenisobjekt, promise = Ergebnisproduzent
@ -4072,20 +4069,19 @@ $\Rightarrow$ call-by-name, call-by-value
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-089} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-future-task}
\end{center} \end{center}
\paragraph{Beispiel} Beispiel
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-090} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-41}
\end{center} \end{center}
\subsubsection{Deklarative Parallelisierung mit OpenMP} \subsubsection{Deklarative Parallelisierung mit OpenMP}
\begin{itemize*} \begin{itemize*}
\item Programmierschnittstelle für Parallelisierung in C/C++/Fortran \item Programmierschnittstelle für Parallelisierung in C/C++/Fortran
\item Programmiersprachenerweiterung durch Direktiven \item Programmiersprachenerweiterung durch Direktiven
\item in C/C++: \#pragma omp \item in C/C++: \#pragma omp ...
\item zusätzliche Bibliotheksfunktionen: \#include <omp.h> \item zusätzliche Bibliotheksfunktionen: \#include <omp.h>
\item aktuelle Version 5.0 \item aktuelle Version 5.0
\item Unterstützung in gcc und clang \item Unterstützung in gcc und clang
@ -4104,7 +4100,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item Fortsetzung des Master-Threads \item Fortsetzung des Master-Threads
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.2\linewidth]{Assets/Programmierparadigmen-091} \includegraphics[width=0.2\linewidth]{Assets/Programmierparadigmen-master-worker-thread}
\end{center} \end{center}
@ -4114,12 +4110,12 @@ $\Rightarrow$ call-by-name, call-by-value
\item Ende des parallelen Abschnitts $\rightarrow$ implizite Synchronisation $\rightarrow$ Fortsetzung des Master-Threads \item Ende des parallelen Abschnitts $\rightarrow$ implizite Synchronisation $\rightarrow$ Fortsetzung des Master-Threads
\item der dem 'pragma' folgende Block wird parallel von allen Threads ausgeführt \item der dem 'pragma' folgende Block wird parallel von allen Threads ausgeführt
\begin{lstlisting}[language=C++] \begin{lstlisting}[language=C++]
\#include <iostream> #include <iostream>
\#include <omp.h> #include <omp.h>
int main() { int main() {
\#pragma omp parallel #pragma omp parallel
{ {
std::cout << "Hello World from thread \#" std::cout << "Hello World from thread #"
<< omp_get_thread_num() << " of " << omp_get_thread_num() << " of "
<< omp_get_num_threads() << "\n"; << omp_get_num_threads() << "\n";
} }
@ -4130,7 +4126,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item Schleifenparallelisierung: jedem Thread wird ein Teil der Iteration zugewiesen (beeinflusst nur äußere Schleife) \item Schleifenparallelisierung: jedem Thread wird ein Teil der Iteration zugewiesen (beeinflusst nur äußere Schleife)
\begin{lstlisting}[language=C++] \begin{lstlisting}[language=C++]
... ...
\#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < 20; i++) {... for (int i = 0; i < 20; i++) {...
\end{lstlisting} \end{lstlisting}
\begin{itemize*} \begin{itemize*}
@ -4162,7 +4158,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item '\#pragma omp single/master' Abschnitt wird nur durch einen/den Master-Thread ausgeführt \item '\#pragma omp single/master' Abschnitt wird nur durch einen/den Master-Thread ausgeführt
\item '\#pragma omp critical' kritischer Abschnitt \item '\#pragma omp critical' kritischer Abschnitt
\item '\#pragma omp barrier' Warten auf alle Worker-Threads \item '\#pragma omp barrier' Warten auf alle Worker-Threads
\item '\#pragma omp atomic' kritischer Abschnitt \item Zugriff auf gemeinsame Variable (z.B. Zähler) \item '\#pragma omp atomic' kritischer Abschnitt, Zugriff auf gemeinsame Variable (z.B. Zähler)
\end{itemize*} \end{itemize*}
\item Speicherklauseln für Variablen \item Speicherklauseln für Variablen
\begin{itemize*} \begin{itemize*}
@ -4173,11 +4169,11 @@ $\Rightarrow$ call-by-name, call-by-value
\end{itemize*} \end{itemize*}
\item zuweisung von Programmabschnitten zu Threads $\rightarrow$ statische Parallelität (geeignet für rekursive Abschnitte) \item zuweisung von Programmabschnitten zu Threads $\rightarrow$ statische Parallelität (geeignet für rekursive Abschnitte)
\begin{lstlisting}[language=C++] \begin{lstlisting}[language=C++]
\#pragma omp parallel sections #pragma omp parallel sections
{ {
\#pragma omp section #pragma omp section
qsort(data, left, p \item 1); qsort(data, left, p - 1);
\#pragma omp section #pragma omp section
qsort(data, p + 1, right); qsort(data, p + 1, right);
} }
\end{lstlisting} \end{lstlisting}
@ -4189,11 +4185,11 @@ $\Rightarrow$ call-by-name, call-by-value
\end{itemize*} \end{itemize*}
\begin{lstlisting}[language=C++] \begin{lstlisting}[language=C++]
unsigned int f1, f2; unsigned int f1, f2;
\#pragma omp task shared(f1) #pragma omp task shared(f1)
f1 = fib(f \item 1); f1 = fib(f - 1);
\#pragma omp task shared(f2) #pragma omp task shared(f2)
f2 = fib(f \item 2); f2 = fib(f - 2);
\#pragma omp taskwait #pragma omp taskwait
return f1 + f2; return f1 + f2;
\end{lstlisting} \end{lstlisting}
\end{itemize*} \end{itemize*}
@ -4203,7 +4199,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item der dem pragma folgende Block wird parallel von allen Threads ausgeführt \item der dem pragma folgende Block wird parallel von allen Threads ausgeführt
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-092} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-42}
\end{center} \end{center}
\subsubsection{Schleifenparallelisierung} \subsubsection{Schleifenparallelisierung}
@ -4212,17 +4208,18 @@ $\Rightarrow$ call-by-name, call-by-value
\item für for-Schleifgen mit eingeschränkter Syntax (ganzzahlige Schleifenvariablen, Operatoren auf Schleifenvariablen) und für STL-Iteratoren \item für for-Schleifgen mit eingeschränkter Syntax (ganzzahlige Schleifenvariablen, Operatoren auf Schleifenvariablen) und für STL-Iteratoren
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-093} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-43}
\end{center} \end{center}
\subsubsection{Beeinflussung der Thread-Anzahl} \subsubsection{Beeinflussung der Thread-Anzahl}
maximale Anzahl maximale Anzahl
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-094} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-44}
\end{center} \end{center}
\noindent \noindent
bedingte Parallelisierung bedingte Parallelisierung
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-095} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-45}
\end{center} \end{center}
\subsubsection{Aufteilung des Iterationsbereichs} \subsubsection{Aufteilung des Iterationsbereichs}
@ -4234,7 +4231,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item schedule(static,n): statische Round-Robin-Verteilung - Bereiche der Größe n (Angabe von n ist optional) \item schedule(static,n): statische Round-Robin-Verteilung - Bereiche der Größe n (Angabe von n ist optional)
\item schedule(dynamic, n): dynamische Verteilung nach Bedarf \item schedule(dynamic, n): dynamische Verteilung nach Bedarf
\item schedule(guided, n): Verteilung nach Bedarf und proportional zur Restarbeit \item schedule(guided, n): Verteilung nach Bedarf und proportional zur Restarbeit
\item \item ...
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
@ -4245,7 +4242,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item Beispiel: Matrizenmultiplikation \item Beispiel: Matrizenmultiplikation
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-096} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-46}
\end{center} \end{center}
\subsubsection{Synchronisation} \subsubsection{Synchronisation}
@ -4272,7 +4269,7 @@ $\Rightarrow$ call-by-name, call-by-value
\item geeignet z.B. für rekursive Aufrufe \item geeignet z.B. für rekursive Aufrufe
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-097} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-47}
\end{center} \end{center}
\subsubsection{Task-Programmierung mit OpenMP} \subsubsection{Task-Programmierung mit OpenMP}
@ -4285,7 +4282,7 @@ $\Rightarrow$ call-by-name, call-by-value
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-098} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-48}
\end{center} \end{center}
\subsubsection{Fazit} \subsubsection{Fazit}
@ -4293,18 +4290,15 @@ $\Rightarrow$ call-by-name, call-by-value
\item C++ bietet weitreichende und mächtige Konzepte zur Parallelisierung \item C++ bietet weitreichende und mächtige Konzepte zur Parallelisierung
\begin{itemize*} \begin{itemize*}
\item von Basiskontrolle wie Threads und Synchronisationsprimitiven (u.a. Mutexe) \item von Basiskontrolle wie Threads und Synchronisationsprimitiven (u.a. Mutexe)
\item über höherwertige Abstraktionen wie async, Features und Promises \item ...über höherwertige Abstraktionen wie async, Features und Promises
\item bis hin zu deklarativen Ansätzen wie OpenMP \item bis hin zu deklarativen Ansätzen wie OpenMP
\end{itemize*} \end{itemize*}
\item alle Formen von Parallelität (Instruktions-, Daten-, und Taskparallelität) möglich \item alle Formen von Parallelität (Instruktions-, Daten-, und Taskparallelität) möglich
\item aber anspruchsvolle Programmierung \item aber anspruchsvolle Programmierung
\item erleichtert durch zusätzliche Bibliotheken und Frameworks wie Parallel STL, TBB, \item erleichtert durch zusätzliche Bibliotheken und Frameworks wie Parallel STL, TBB, ...
\end{itemize*} \end{itemize*}
\begin{lstlisting}[
language=java, \begin{lstlisting}[language=java]
showspaces=false,
basicstyle=\ttfamily
]
//[Hello.java] //[Hello.java]
package runnable; package runnable;
public class Hello { public class Hello {
@ -4328,12 +4322,7 @@ public class Hello {
} }
\end{lstlisting} \end{lstlisting}
\hfill \hfill
\begin{lstlisting}[language=C++]
\begin{lstlisting}[
language=C++,
showspaces=false,
basicstyle=\ttfamily
]
//[Hello.cpp] //[Hello.cpp]
#include <iostream> // Datei iostream aus System-Includes #include <iostream> // Datei iostream aus System-Includes
#include "X.hpp" // Datei X.hpp aus Projekt-Ordner #include "X.hpp" // Datei X.hpp aus Projekt-Ordner
@ -4368,12 +4357,7 @@ int main(int argc, char* argv[]){
} }
\end{lstlisting} \end{lstlisting}
\hfill \hfill
\begin{lstlisting}[language=erlang]
\begin{lstlisting}[
language=erlang,
showspaces=false,
basicstyle=\ttfamily
]
%[Hello.erl] %[Hello.erl]
-module(cheat_sheet). % end with a period -module(cheat_sheet). % end with a period
@ -4441,11 +4425,7 @@ countdown() $\rightarrow$
\begin{itemize*} \begin{itemize*}
\item Methode \textbf{public void run()} - wird beim Start des Threads aufgerufen \item Methode \textbf{public void run()} - wird beim Start des Threads aufgerufen
\end{itemize*} \end{itemize*}
\begin{center} \begin{lstlisting}[language=java]
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-099}
\end{center}
\begin{lstlisting}[
language=java]
public class Heartbeat implements Runnable { public class Heartbeat implements Runnable {
int pulse; int pulse;
public Heartbeat(int p) { pulse = p * 1000; } public Heartbeat(int p) { pulse = p * 1000; }
@ -4457,11 +4437,6 @@ countdown() $\rightarrow$
} }
} }
} }
public static void main(String[] args) {
Thread t = new Thread(new Heartbeat(2)); //Thread Objekt mit runnable erzeugen
t.start(); //methode start() aufrufen $\rightarrow$ ruft run() auf
}
\end{lstlisting} \end{lstlisting}
\paragraph{Thread-Erzeugung} \paragraph{Thread-Erzeugung}
@ -4473,9 +4448,12 @@ countdown() $\rightarrow$
\item Ruft \textbf{run()} auf \item Ruft \textbf{run()} auf
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\begin{center} \begin{lstlisting}[language=java]
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-100} public static void main(String[] args) {
\end{center} Thread t = new Thread(new Heartbeat(2)); //Thread Objekt mit runnable erzeugen
t.start(); //methode start() aufrufen $\rightarrow$ ruft run() auf
}
\end{lstlisting}
\paragraph{Subklasse von Thread} \paragraph{Subklasse von Thread}
@ -4484,7 +4462,7 @@ countdown() $\rightarrow$
\item Methode run() muss überschrieben werden \item Methode run() muss überschrieben werden
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-101} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-49}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
@ -4495,52 +4473,32 @@ countdown() $\rightarrow$
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\centering \centering
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-102} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-50}
\end{center} \end{center}
\item Spätere Beeinflussung durch andere Threads möglich \item Spätere Beeinflussung durch andere Threads möglich
\begin{center} \begin{center}
\centering \centering
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-103} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-51}
\end{center} \end{center}
\end{itemize*} \end{itemize*}
\paragraph{Threads: Wichtige Methoden} \paragraph{Threads: Wichtige Methoden}
\begin{itemize*} \begin{description*}
\item void start(): initiiert Ausführung des Threads durch Aufruf der Methode run \item[void start()] initiiert Ausführung des Threads durch Aufruf der Methode run
\item void run(): die eigentliche Arbeitsmethode \item[void run()] die eigentliche Arbeitsmethode
\item static void sleep(int millis): hält die Ausführung des aktuellen Threads für 'millis' Millisekunden an; Keinen Einfluss auf andere Threads! \item[static void sleep(int millis)] hält die Ausführung des aktuellen Threads für 'millis' Millisekunden an; Keinen Einfluss auf andere Threads!
\item void join(): blockiert den aufrufenden Thread so lange, bis der aufgerufene Thread beendet ist \item[void join()] blockiert den aufrufenden Thread so lange, bis der aufgerufene Thread beendet ist
\end{itemize*} \end{description*}
\begin{itemize*}
\item \textbf{void start()}
\begin{itemize*}
\item initiiert Ausführung des Threads durch Aufruf der Methode run
\end{itemize*}
\item \textbf{void run()}
\begin{itemize*}
\item die eigentliche Arbeitsmethode
\end{itemize*}
\item \textbf{static void sleep(int millisec)}
\begin{itemize*}
\item hält die Ausführung des aktuellen Threads für millisec Millisekunden an
\item Hat keinen Einfluss auf andere Threads!
\end{itemize*}
\item \textbf{void join()}
\begin{itemize*}
\item blockiert den aufrufenden Thread so lange, bis der aufgerufene Thread beendet ist
\end{itemize*}
\end{itemize*}
\subsubsection{Parallele Berechnung von Fibonacci-Zahlen} \subsubsection{Parallele Berechnung von Fibonacci-Zahlen}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-104} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-52}
\end{center} \end{center}
Thread-Erzeugung und Ausführung Thread-Erzeugung und Ausführung
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-105} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-53}
\end{center} \end{center}
\subsubsection{Wechselseitiger Ausschluss in Java} \subsubsection{Wechselseitiger Ausschluss in Java}
@ -4555,14 +4513,14 @@ countdown() $\rightarrow$
\begin{itemize*} \begin{itemize*}
\item nur ein Thread darf diese Methode auf einem Objekt zur gleichen Zeit ausführen \item nur ein Thread darf diese Methode auf einem Objekt zur gleichen Zeit ausführen
\end{itemize*} \end{itemize*}
\item für Anweisungen: \textbf{synchronized(anObject)\{\}} \item für Anweisungen: \textbf{synchronized(anObject)\{...\}}
\begin{itemize*} \begin{itemize*}
\item nur ein Thread darf den Block betreten \item nur ein Thread darf den Block betreten
\item Sperre wird durch das Objekt \textbf{anObject} verwaltet (jedem Java-Objekt ist eine Sperre zugeordnet) \item Sperre wird durch das Objekt \textbf{anObject} verwaltet (jedem Java-Objekt ist eine Sperre zugeordnet)
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-106} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-java-synchronized}
\end{center} \end{center}
\begin{itemize*} \begin{itemize*}
\item Schlüsselwort synchronized \item Schlüsselwort synchronized
@ -4584,23 +4542,14 @@ countdown() $\rightarrow$
\end{itemize*} \end{itemize*}
\subsubsection{wait \& notify} \subsubsection{wait \& notify}
\begin{itemize*} \begin{description*}
\item Signalisierung zwischen Threads in Java \item[] Signalisierung zwischen Threads in Java
\item Basismethoden der Klasse \textbf{java.lang.Object} \item[] Basismethoden der Klasse \textbf{java.lang.Object}
\item \textbf{wait()}: der aktive Thread wartet an diesem Objekt, Sperren werden ggf. freigegeben. \item[wait()] der aktive Thread wartet an diesem Objekt, Sperren werden ggf. freigegeben.
\item \textbf{notify()}: wekct an diesem Objekt wartenden Thread auf \item[notify()] wekct an diesem Objekt wartenden Thread auf
\item \textbf{notifyAll()}: weckt alle an diesem Objekt wartenden Threads auf \item[notifyAll()] weckt alle an diesem Objekt wartenden Threads auf
\item \textbf{wait() \& notify()} dürfen nur in einem \textbf{synchronized}-Block aufgerufen werden \item[wait() \& notify()] dürfen nur in einem \textbf{synchronized}-Block aufgerufen werden
\end{itemize*} \end{description*}
\begin{itemize*}
\item Signalisierung zwischen Threads in Java
\item Basismethoden der Klasse java.lang.Object
\item wait() : der aktive Thread wartet an diesem Objekt, Sperren werden ggf. freigegeben!
\item notify() : weckt an diesem Objekt wartenden Thread auf
\item notifyAll() : weckt alle an diesem Objekt wartenden Threads auf
\item wait() \& notify() dürfen nur in einem synchronized -Block aufgerufen werden
\end{itemize*}
\subsubsection{Java: High-Level-Klassen} \subsubsection{Java: High-Level-Klassen}
\begin{itemize*} \begin{itemize*}
@ -4619,12 +4568,9 @@ countdown() $\rightarrow$
\item Task = logische Ausführungseinheit \item Task = logische Ausführungseinheit
\item Thread = Mechanismus zur asynchronen/parallelen Ausführung von Tasks \item Thread = Mechanismus zur asynchronen/parallelen Ausführung von Tasks
\end{itemize*} \end{itemize*}
\begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-107} \begin{lstlisting}[language=java]
\end{center} Runnable task = () -> {
\begin{lstlisting}[
language=java]
Runnable task = () $\rightarrow$ {
String me = Thread.currentThread().getName(); String me = Thread.currentThread().getName();
System.out.println("Hallo " + me); System.out.println("Hallo " + me);
}; };
@ -4642,8 +4588,8 @@ thread.start();
\end{itemize*} \end{itemize*}
\item Starten einer Aufgabe mit \textbf{submit} \item Starten einer Aufgabe mit \textbf{submit}
\begin{itemize*} \begin{itemize*}
\item \textbf{Future<T> submit(Callable c)} \item \textbf{$Future<T>$ submit(Callable c)}
\item \textbf{Future<?> submit(Runnable r)} \item \textbf{$Future<?>$ submit(Runnable r)}
\end{itemize*} \end{itemize*}
\item Zugriff auf das Ergebnis mit \textbf{get} \item Zugriff auf das Ergebnis mit \textbf{get}
\begin{itemize*} \begin{itemize*}
@ -4655,7 +4601,7 @@ thread.start();
\paragraph{Future \& ExecutorService: Beispiel} \paragraph{Future \& ExecutorService: Beispiel}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-108} \includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-code-snippet-54}
\end{center} \end{center}
\subsubsection{RecursiveAction \& Fork/Join} \subsubsection{RecursiveAction \& Fork/Join}
@ -4664,10 +4610,6 @@ thread.start();
\item Solange bis Problem klein genug um direkt ausgeführt werden zu können \item Solange bis Problem klein genug um direkt ausgeführt werden zu können
\item Task erstellt zwei oder mehr Teiltasks von sich selbst $\rightarrowtail$ Datenparallelität \item Task erstellt zwei oder mehr Teiltasks von sich selbst $\rightarrowtail$ Datenparallelität
\item ForkJoinPool zum Ausführen $\rightarrow$ implementiert Executor Interface \item ForkJoinPool zum Ausführen $\rightarrow$ implementiert Executor Interface
\item \textbf{ForkJoinPool} zum Ausführen
\begin{itemize*}
\item implementiert \textbf{Executor} Interface
\end{itemize*}
\item Fazit \item Fazit
\begin{itemize*} \begin{itemize*}
\item Parallelprogrammierung in Java sehr ähnlich zu C++ \item Parallelprogrammierung in Java sehr ähnlich zu C++
@ -4684,7 +4626,7 @@ thread.start();
\paragraph{Beispiel} \paragraph{Beispiel}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-109} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-55}
\end{center} \end{center}
Starten der Verarbeitung: Starten der Verarbeitung:
\begin{enumerate*} \begin{enumerate*}
@ -4693,24 +4635,12 @@ thread.start();
\item Aufgabe vom Pool ausführen lassen \item Aufgabe vom Pool ausführen lassen
\end{enumerate*} \end{enumerate*}
\begin{center} \begin{center}
\includegraphics[width=0.7\linewidth]{Assets/Programmierparadigmen-110} \includegraphics[width=0.4\linewidth]{Assets/Programmierparadigmen-code-snippet-56}
\end{center} \end{center}
\subsubsection{Fazit}
\begin{itemize*}
\item Parallelprogrammierung in Java sehr ähnlich zu C++
\item Konzepte: Threads, kritische Abschnitte über \textbf{synchronized}
\item mächtige Abstraktionen in \textbf{java.util.concurrent}
\begin{itemize*}
\item Tasks und Futures, Executor und Threadpool
\item thread-sichere Datenstrukturen
\item Synchronisation: Barrieren, Semaphoren,…
\end{itemize*}
\end{itemize*}
\subsection{Zusammenfassung} \subsection{Zusammenfassung}
\begin{itemize*} \begin{itemize*}
\item Parallelprogrammierung als wichtige Technik zur Nutzung moderner Hardware (Multicore, GPU, ) \item Parallelprogrammierung als wichtige Technik zur Nutzung moderner Hardware (Multicore, GPU, ...)
\item verschiedene Architekturen und Programmiermodelle \item verschiedene Architekturen und Programmiermodelle
\item Instruktions-, Daten- und Taskparallelität \item Instruktions-, Daten- und Taskparallelität
\item Message Passing vs. gemeinsamer Speicher \item Message Passing vs. gemeinsamer Speicher
@ -4764,9 +4694,8 @@ thread.start();
\begin{itemize*} \begin{itemize*}
\item Datei \~/.erlang.cookie \item Datei \~/.erlang.cookie
\item Erlang-Funktion \item Erlang-Funktion
\begin{lstlisting}[ \begin{lstlisting}[language=erlang]
language=erlang, :set_cookie(node(), Cookie).
]:set_cookie(node(), Cookie).
\end{lstlisting} \end{lstlisting}
\item Option \item Option
\begin{lstlisting} \begin{lstlisting}
@ -4847,7 +4776,7 @@ thread.start();
\end{itemize*} \end{itemize*}
\item Knoten sind über Netzwerke verbunden \item Knoten sind über Netzwerke verbunden
\begin{itemize*} \begin{itemize*}
\item LAN(Wohnräume, Büros,): bis zu 10 Gbit/s \item LAN(Wohnräume, Büros,...): bis zu 10 Gbit/s
\item MAN(Metropolitan Area Network, Behördennetze, dicht besiedelte Regionen): bis zu 10 Gbit/s \item MAN(Metropolitan Area Network, Behördennetze, dicht besiedelte Regionen): bis zu 10 Gbit/s
\item WAN(Wide Area Network, weltweite Vernetzung): hohe Kapazitäten zwischen den ISPs \item WAN(Wide Area Network, weltweite Vernetzung): hohe Kapazitäten zwischen den ISPs
\end{itemize*} \end{itemize*}
@ -4882,8 +4811,8 @@ thread.start();
\item Middlewaresysteme: Hardware, OS, Middleware, Anwendung \item Middlewaresysteme: Hardware, OS, Middleware, Anwendung
\begin{itemize*} \begin{itemize*}
\item verteilte Dienste \item verteilte Dienste
\item Programmierparadigmen: RPC, Client/Server, \item Programmierparadigmen: RPC, Client/Server,...
\item Java, CORBA, \item Java, CORBA, ...
\end{itemize*} \end{itemize*}
\item Heute: Virtualisierung \item Heute: Virtualisierung
\begin{itemize*} \begin{itemize*}
@ -4906,9 +4835,9 @@ thread.start();
\color{orange} $\Rightarrow$ brauchen Modelle zur Beschreibung der Kommunikation \color{black} \color{orange} $\Rightarrow$ brauchen Modelle zur Beschreibung der Kommunikation \color{black}
\subsubsection{Anforderungen} \subsubsection{Anforderungen}
\color{orange} Anforderungen an Kommunikationsmodelle in \color{black} \color{orange} Anforderungen an Kommunikationsmodelle in ... \color{black}
\newline \newline
verteilten Systemen\newline \newline ... verteilten Systemen\newline \newline
\begin{itemize*} \begin{itemize*}
\item Korrektheit \item Korrektheit
\item Sicherheit \item Sicherheit
@ -4917,7 +4846,7 @@ thread.start();
\item Heterogenität \item Heterogenität
\end{itemize*} \end{itemize*}
verteilten Verkehrsmanagementsystemen\newline \newline ...verteilten Verkehrsmanagementsystemen\newline \newline
\begin{itemize*} \begin{itemize*}
\item Echtzeitfähigkeit \item Echtzeitfähigkeit
\item Offenheit \item Offenheit
@ -5037,9 +4966,9 @@ thread.start();
\end{itemize*} \end{itemize*}
\item Programmbestandteile im Aktormodell \item Programmbestandteile im Aktormodell
\begin{itemize*} \begin{itemize*}
\item Verhaltensdefinition $\Rightarrow$ f() $\rightarrow$ end. \item Verhaltensdefinition $\Rightarrow$ f() $\rightarrow$ ... end.
\item Erzeugen neuer Aktoren $\Rightarrow$ Pid = spwan(fun ). \item Erzeugen neuer Aktoren $\Rightarrow$ Pid = spwan(fun ...).
\item Empfangen von Nachrichten $\Rightarrow$ receive end. \item Empfangen von Nachrichten $\Rightarrow$ receive ... end.
\item Senden $\Rightarrow$ Pid ! Request. \item Senden $\Rightarrow$ Pid ! Request.
\end{itemize*} \end{itemize*}
\item kein globaler Zustand \item kein globaler Zustand
@ -5144,7 +5073,7 @@ ok
\end{center} \end{center}
drei Prozesse mit \textbf{initialize(ErrorRate, NumberOfMessages, ReceiverPid, SenderPid, ChannelPid)} initialisieren und starten drei Prozesse mit \textbf{initialize(ErrorRate, NumberOfMessages, ReceiverPid, SenderPid, ChannelPid)} initialisieren und starten
\begin{itemize*} \begin{itemize*}
\item Sender hat vier Zustandsfunktionen; Startet mit senderReady0(List): Liste mit Zahlen 1,,NumberOfMessages \item Sender hat vier Zustandsfunktionen; Startet mit senderReady0(List): Liste mit Zahlen 1,...,NumberOfMessages
\item Kanal: Nachricht "verlieren", wenn Zufallszahl $\ngeq$ ErrorRate \item Kanal: Nachricht "verlieren", wenn Zufallszahl $\ngeq$ ErrorRate
\item Empfänger hat zwei Zustandsfunktionen; zu Beginn wird receiverWait0 gestartet \item Empfänger hat zwei Zustandsfunktionen; zu Beginn wird receiverWait0 gestartet
\item initialize wartet auf eine ready-Nachricht; sendet danach stop-Nachrichten an alle \item initialize wartet auf eine ready-Nachricht; sendet danach stop-Nachrichten an alle
@ -5476,7 +5405,7 @@ end
\item Clients: "Gib mir alle Personen, die älter als 18 Jahre alt sind" \item Clients: "Gib mir alle Personen, die älter als 18 Jahre alt sind"
\end{itemize*} \end{itemize*}
\item \textbf{Web}: Webserver stellt HTML Dokumente bereit, Brwoser ruft URLs für Dokumente auf \item \textbf{Web}: Webserver stellt HTML Dokumente bereit, Brwoser ruft URLs für Dokumente auf
\item \textbf{E-Mail}: Mailserver verwalten Postfächer, leiten Mails weiter, Outlook/Thunderbird/senden/lesen von Emails \item \textbf{E-Mail}: Mailserver verwalten Postfächer, leiten Mails weiter, Outlook/Thunderbird/...senden/lesen von Emails
\item Namensdienste (DNS), Fileserver, Zeitserver (NTP) \item Namensdienste (DNS), Fileserver, Zeitserver (NTP)
\end{itemize*} \end{itemize*}
@ -5579,7 +5508,7 @@ end
\item oftmals existiert ein HTTP Server / Anwendungsserver schon \item oftmals existiert ein HTTP Server / Anwendungsserver schon
\item Idee: Jede Ressource die vom Server angeboten wird, ist durch eine URI beschrieben/identifiziert \item Idee: Jede Ressource die vom Server angeboten wird, ist durch eine URI beschrieben/identifiziert
\begin{itemize*} \begin{itemize*}
\item Datei, ein Eintrag in einer Datenbank, Tweet, \item Datei, ein Eintrag in einer Datenbank, Tweet,...
\end{itemize*} \end{itemize*}
\item Anlegen, Lesen, Verändern, Löschen (CRUD) \item Anlegen, Lesen, Verändern, Löschen (CRUD)
\begin{itemize*} \begin{itemize*}
@ -5599,7 +5528,7 @@ end
\item bei jeder Anfrage werden alle Informationen gesendet \item bei jeder Anfrage werden alle Informationen gesendet
\end{itemize*} \end{itemize*}
\item Einheitliche Schnittstelle: über HTTP Standardmethoden auf Ressourcen zugreifen \item Einheitliche Schnittstelle: über HTTP Standardmethoden auf Ressourcen zugreifen
\item Entkopplung von Ressource und Repräsentation: Ressourcen können in verschiedenen Formaten angeboten werden (JSON, XML,) \item Entkopplung von Ressource und Repräsentation: Ressourcen können in verschiedenen Formaten angeboten werden (JSON, XML,...)
\end{enumerate*} \end{enumerate*}
\paragraph{HTTP Methoden für REST} \paragraph{HTTP Methoden für REST}
@ -5636,7 +5565,7 @@ end
\begin{itemize*} \begin{itemize*}
\item manuelle Implementierung recht aufwändig \item manuelle Implementierung recht aufwändig
\begin{itemize*} \begin{itemize*}
\item unterscheiden von HTTP Methoden (GET, POST,) \item unterscheiden von HTTP Methoden (GET, POST,...)
\item parsen/prüfen von URL Pfaden und Parametern \item parsen/prüfen von URL Pfaden und Parametern
\item setzen von Antwortheadern \& Kodierung in XML/JSON \item setzen von Antwortheadern \& Kodierung in XML/JSON
\end{itemize*} \end{itemize*}
@ -5687,7 +5616,7 @@ end
https://reques.in kostenloser Dienst zum Testen von REST-Clients https://reques.in kostenloser Dienst zum Testen von REST-Clients
\begin{itemize*} \begin{itemize*}
\item Variante 1: telnet reques.in 80 \item Variante 1: telnet reques.in 80 ...
\item Variante 2: Auf der Kommandozeile \newline \item Variante 2: Auf der Kommandozeile \newline
\$ curl https://reqres.in/api/users/1 \$ curl https://reqres.in/api/users/1
\begin{center} \begin{center}
@ -6066,7 +5995,7 @@ fileservice.proto
\begin{itemize*} \begin{itemize*}
\item erhebliche Management-Last beim Vermittler \item erhebliche Management-Last beim Vermittler
\begin{itemize*} \begin{itemize*}
\item potentieller Engpass, SPoF - es sei denn \item potentieller Engpass, SPoF - es sei denn...
\end{itemize*} \end{itemize*}
\end{itemize*} \end{itemize*}
Variante: mehrere Vermittler-Instanzen parallel und verteilt in einer Clusterumgebung Variante: mehrere Vermittler-Instanzen parallel und verteilt in einer Clusterumgebung