diff options
Diffstat (limited to 'LaTeX/chapters')
| -rw-r--r-- | LaTeX/chapters/anhang-a.tex | 3 | ||||
| -rw-r--r-- | LaTeX/chapters/einleitung.tex | 4 | ||||
| -rw-r--r-- | LaTeX/chapters/implementierung.tex | 51 | ||||
| -rw-r--r-- | LaTeX/chapters/protokolle.tex | 60 | ||||
| -rw-r--r-- | LaTeX/chapters/simulator.tex | 32 |
5 files changed, 80 insertions, 70 deletions
diff --git a/LaTeX/chapters/anhang-a.tex b/LaTeX/chapters/anhang-a.tex index d386b3d..e9222e0 100644 --- a/LaTeX/chapters/anhang-a.tex +++ b/LaTeX/chapters/anhang-a.tex @@ -8,6 +8,7 @@ \acro{GUI}{Graphical User Interface}
\acro{GVim}{Graphical Vi IMproved}
\acro{HTTPS}{Hypertext Transfer Protocol Secure}
+\acro{IP}{Internet Protocol}
\acro{JRE}{Java Runtime Environment}
\acro{NID}{Nachrichten-Identifikationsnummer}
\acro{PDF}{Protable Document Format}
@@ -15,5 +16,7 @@ \acro{RTT}{Round Trip Time}
\acro{SDK}{Software Development Kit}
\acro{SVN}{Subversion}
+\acro{TCP}{Transmission Control Protocol}
+\acro{UDP}{User Datagram Protocol}
\acro{VS}{Verteilte Systeme}
\end{acronym}
diff --git a/LaTeX/chapters/einleitung.tex b/LaTeX/chapters/einleitung.tex index 2374c1b..fd75fbb 100644 --- a/LaTeX/chapters/einleitung.tex +++ b/LaTeX/chapters/einleitung.tex @@ -29,7 +29,7 @@ Der Simulator basiert auf dem Client/Server-Prinzip. Jede Simulation besteht in \subsubsection{Prozesse und deren Rollen} -Ein verteiltes System wird anhand von Prozessen simuliert. Jeder Prozess nimmt hierbei eine oder mehrere Rollen ein. Beispielsweise kann ein Prozess die Rolle eines Clients einnehmen und ein weiterer Prozess die Rolle eines Servers. Die M\"{o}glichkeit einem Prozess die Client- und Serverrolle gleichzeitig zuzuweisen ist ebenso gegeben. Ein Prozess k\"{o}nnte auch die Rollen mehrerer Server und Clients gleichzeitig einnehmen. Um einen Prozess zu kennzeichnen besitzt, jeder eine \textbf{eindeutige} Prozess-Identifikationsnummer (PID). +Ein verteiltes System wird anhand von Prozessen simuliert. Jeder Prozess nimmt hierbei eine oder mehrere Rollen ein. Beispielsweise kann ein Prozess die Rolle eines Clients einnehmen und ein weiterer Prozess die Rolle eines Servers. Die M\"{o}glichkeit einem Prozess die Client- und Serverrolle gleichzeitig zuzuweisen ist ebenso gegeben. Ein Prozess k\"{o}nnte auch die Rollen mehrerer Server und Clients gleichzeitig einnehmen. Um einen Prozess zu kennzeichnen, besitzt jeder eine \textbf{eindeutige} Prozess-Identifikationsnummer (PID). \subsubsection{Nachrichten} @@ -48,7 +48,7 @@ Zudem besitzt jeder beteiligte Prozess eine eigene lokale Uhr. Sie stellt die ak \label{fig:ClientServerProtokolle} \end{figure} -Neben den normalen Uhren sind auch die Vektor-Zeitstempel sowie die logischen Uhren von Lamport von Interesse. Jeder Prozess besitzt zusätzlich einen Vektor-Zeitstempel für seine Vektorzeit, sowie einen Lamport-Zeitstempel für seine Lamportzeit. Für die Vektor- und Lamportzeiten gibt es hier, im Gegensatz zu der normalen Zeit, keine globalen Äquivalente. Konkrete Beispiele zu den Lamport- und Vektorzeiten werden später in Kapitel 3.11.1. behandelt. +Neben den normalen Uhren sind auch die Vektor-Zeitstempel sowie die logischen Uhren von Lamport von Interesse. Für die Vektor- und Lamportzeiten gibt es hier, im Gegensatz zu der normalen Zeit, keine globalen Äquivalente. Konkrete Beispiele zu den Lamport- und Vektorzeiten werden später in Kapitel 3.11.1. behandelt. \subsubsection{Ereignisse} diff --git a/LaTeX/chapters/implementierung.tex b/LaTeX/chapters/implementierung.tex index 29e451b..4c7c683 100644 --- a/LaTeX/chapters/implementierung.tex +++ b/LaTeX/chapters/implementierung.tex @@ -34,7 +34,7 @@ Der Verlauf einer Simulation ist von einer Vielzahl von Einstellungen abhängig. \subsubsection{Einstellungsobjekte}
-In Abbildung \ref{fig:PackagePrefs}. ist der Aufbau des Pakets \textit{prefs} zu sehen. In einer Instanz der Klasse \textit{VSPrefs} lassen sich viele verschiedene Daten als Variablen für eine spätere Verwendung dynamisch ablegen, damit stellt somit einen Container für diese Daten dar. In einem \textit{VSPrefs}-Objekt speichert der Simulator alle Einstellungen ab. Zudem besitzt jedes Prozessobjekt und jedes Ereignisobjekt für lokale Einstellungen seine eigene Instanz von \textit{VSPrefs}. Später wird gezeigt, wie Protokollobjekte auch als Ereignisse eingesetzt werden, womit Protokolleinstellungen auch in einem \textit{VSPrefs}-Objekt abgespeichert werden k\"{o}nnen. Auch Nachrichtenobjekte besitzt hiervon eine eigene Instanz dieser Klasse, um die zu verschickenden Daten zwischen zu speichern.
+In Abbildung \ref{fig:PackagePrefs}. ist der Aufbau des Pakets \textit{prefs} zu sehen. In einer Instanz der Klasse \textit{VSPrefs} lassen sich viele verschiedene Daten als Variablen für eine spätere Verwendung dynamisch ablegen, damit stellt eine solche Instanz einen Container für diese Daten dar. In einem \textit{VSPrefs}-Objekt speichert der Simulator alle Einstellungen ab. Zudem besitzt jedes Prozessobjekt und jedes Ereignisobjekt für lokale Einstellungen seine eigene Instanz von \textit{VSPrefs}. Später wird gezeigt, wie Protokollobjekte auch als Ereignisse eingesetzt werden, womit Protokolleinstellungen auch in einem \textit{VSPrefs}-Objekt abgespeichert werden k\"{o}nnen. Auch Nachrichtenobjekte besitzt hiervon eine eigene Instanz dieser Klasse, um die zu verschickenden Daten zwischen zu speichern.
\begin{figure}[h]
\centering
@@ -84,15 +84,15 @@ Im Folgenden werden einige der existierenden Methoden aufgelistet, eine komplett \label{tb:VariablenPraefixe}
\end{table}
-Hierbei steht \textit{key} f\"{u}r den Variablennamen- und \textit{val} f\"{u}r den Variablenwert. \textit{descr} ist die optionale Variablenbeschreibung. Es können sowohl Java's Integer-Objekte, als auch Java's primitiver Integer-Typ \textit{int} verwendet werden. Ein \textit{int}-Wert wird intern zwecks Serialisierbarkeit als Integer-Objekt abgespeichert. Die Methode \textit{getIntegerKeySet} gibt alle vorhandenen Integer-Variablennamen (\textit{key}s) als \textit{Set} TODO zurück.
+Hierbei steht \textit{key} f\"{u}r den Variablennamen- und \textit{val} f\"{u}r den Variablenwert. \textit{descr} ist die optionale Variablenbeschreibung. Es können sowohl Java's Integer-Objekte, als auch Java's primitiver Integer-Typ \textit{int} verwendet werden. Ein \textit{int}-Wert wird intern zwecks Serialisierbarkeit als Integer-Objekt abgespeichert. Die Methode \textit{getIntegerKeySet} gibt alle vorhandenen Integer-Variablennamen (\textit{key}s) als \textit{Set} (s. \cite{Javadoc}) zurück.
Die Klasse \textit{VSPrefs} bietet auch eine Reihe von \textit{initInteger}-Methoden an, welche sich von den \textit{setInteger}-Methoden dadurch unterscheiden, dass sie einer Variable nur einen Wert zuweisen, wenn sie vorher noch nicht initialisiert wurde, was durch \textit{setInteger} oder \textit{initInteger} selbst geschehen sein kann. Eine komplette Übersicht aller Methoden (auch für andere Datentypen) gibt es in der Quelltext-Dokumentation.
Die Klasse \textit{VSPrefs} speichert alle Integervariablen in einem \textit{HashMap<String,Integer>}-Objekt ab, wobei der String-Wert den Variablennamen \textit{key} angibt. Für die Beschreibung \textit{descr}, den Einheiten-String \textit{unit} sowie möglichen Minimal- und Maximalwerte werden separate Instanzen von \textit{HashMap} verwendet. Da die Selektoren von \textit{VSPrefs} synchronisiert sind, können alle \textit{HashMap}s aus verschiednenen Threads gleichzeitig verwendet werden.
-Die Klasse \textit{VSSerializablePrefs} implementiert das Interface \textit{VSSerializable} und kann somit durch Serialisierung alle enthaltenen Daten in eine Datei abspeichern bzw. wieder in den Speicher laden.
+Die Klasse \textit{VSSerializablePrefs} implementiert das Interface \textit{VSSerializable} und kann somit durch Serialisierung alle enthaltenen Daten in eine Datei abspeichern bzw. wieder in den Speicher laden (s. Kap. 4.4.6.).
-Die Klasse \textit{VSDefaultPrefs} erweitert \textit{VSSerializablePrefs} und initialisiert bei ihrer Instantiierung automatisch alle verfügbaren Simulationsvariablen mit Standardwerten. Hier sind auch alle Spracheinstellungen abgelegt. M\"{o}chte man den Simulator in eine andere Sprache (z.B. Englisch) übersetzen wollen, so muss lediglich diese Datei und die Protokoll-Klassen editiert werden. Die Spracheinstellungen sind einem referenzierten \textit{VSPrefs}-Objekt als versteckte String-Variablen abgespeichert. Spracheinstellungen für Protokolle wurden in den Protokollklassen direkt angegeben, da dies mehr Komfort für Protokollentwickler bedeutet und damit für jede neu programmierte Textausgabe nicht \textit{VSDefaultPrefs.java} editiert werden muss.
+Die Klasse \textit{VSDefaultPrefs} erweitert \textit{VSSerializablePrefs} und initialisiert bei ihrer Instantiierung automatisch alle verfügbaren Simulationsvariablen mit Standardwerten. Hier sind auch alle Spracheinstellungen abgelegt. M\"{o}chte man den Simulator in eine andere Sprache (z.B. Englisch) übersetzen, so muss lediglich diese Datei und die Protokoll-Klassen editiert werden. Die Spracheinstellungen sind einem referenzierten \textit{VSPrefs}-Objekt als versteckte String-Variablen abgespeichert. Spracheinstellungen für Protokolle wurden in den Protokollklassen direkt angegeben, da dies mehr Komfort für Protokollentwickler bedeutet und damit für jede neu programmierte Textausgabe nicht \textit{VSDefaultPrefs.java} editiert werden muss.
Alle Variablen die als Präfix \textit{lang}, \textit{keyevent}, \textit{div} oder \textit{col} im Variablennamen tragen, sind versteckte Variablen und werden in einem Editor nicht angezeigt. Im Expertenmodus sind hingegen nur Variablen, die mit \textit{lang} und \textit{keyevent} beginnen, versteckt. Im Expertenmodus lassen sich so weitere Variablen vom Anwender editieren.
@@ -113,7 +113,7 @@ Die Klasse \textit{VSSimulatorEditor} erlaubt das Editieren der globalen Simulat \section{Ereignisse}
-Für jedes Ereignis existiert eine dazugehörige Klasse, welche die auszuführenden Aktionen implementiert. Eine Instanz einer solchen Klasse wird für eine spätere Ausführung dem Task-Manager übergeben.
+Für jedes Ereignis existiert eine dazugehörige Klasse, welche die auszuführenden Aktionen implementiert. Eine Instanz einer solchen Klasse wird für eine spätere Ausführung dem Task-Manager (s. Kap. 4.4.3.) übergeben.
Jedes programmierbare Ereignis muss, bevor es vom Simulator verwendet werden kann, in der statischen Klasse \textit{VSRegisteredEvents} registriert werden. Der Simulator bezieht die Liste aller verf\"{u}gbaren Ereignisse aus \textit{VSRegisterEvents}, wodurch der Entwickler bei der Entwicklung eines neuen Ereignisses keine andere Stelle im Quelltext des Simulators \"{a}ndern muss. Da sich die Anzahl der verfügbaren Ereignisklassen des Simulators bei Laufzeit nicht ändert, gibt es keine Instanzen von \textit{VSRegisteredEvents}. Alle Methoden und Klassenattribute sind statisch. Wenn beispielsweise eigene Ereignisse implementiert werden, dann müssen alle neuen Ereignisse per Hand in der Quelltext-Datei \textit{VSRegisteredEvents.java} übernommen werden, und der Simulator muss neu kompiliert werden.
@@ -143,12 +143,12 @@ In der Implementierung wird zwischen drei Haupttypen von Ereignissen unterschied \item \textit{protocols.implementations}: In diesem Paket befinden sich alle Protokollimplementierung. Jedes Protokoll besitzt seine eigene Klasse. Alle Protokolle erben hierbei von der in Abbildung \ref{fig:PackageEvents}. zu sehenden Klasse \textit{protocols.VSAbstractProtocol}. Da \textit{protocols.VSAbstractProtocol} von \textit{events.VSAbstractEvent} erbt, kann ein Protokollobjekt auch als Ereignis eingesetzt werden. Ein solches Ereignis ruft bei Eintritt entweder die Methode \textit{onServerStart} oder die Methode \textit{onClientStart} des Protokolls auf, was einer Server- bzw. einer Clientanfrage entspricht (s. Kap. 4.4.4.).
\end{enumerate}
-Alle Ereignisse, die das Interface \textit{VSCopyableEvent} implementieren, können vom Anwender im Ereigniseditor mit einem Rechtsklick kopiert werden, des Weiteren müssen sie die Methode \textit{initCopy(VSAbstractEvent copy)} implementieren. Es werden dann alle relevanten Attribute in das neue Ereignis \textit{copy} kopiert.
+Alle Ereignisse, die das Interface \textit{VSCopyableEvent} implementieren, können vom Anwender im Ereigniseditor mit einem Rechtsklick kopiert werden. Des Weiteren müssen sie die Methode \textit{initCopy(VSAbstractEvent copy)} implementieren. Es werden dann alle relevanten Attribute in das neue Ereignis \textit{copy} kopiert.
Alle Ereignisklassen erweitern die abstrakte Klasse \textit{VSAbstractEvent} und müssen folgende abstrakten Methoden implementieren:
\begin{itemize}
- \item \textit{abstract public void onInit()}: Bevor ein Ereignisobjekt vom Simulator verwendet werden kann, muss es initialisiert werden. Je nach Ereignis können verschiedene Werte initialisiert werden. Diese Methode wird pro Ereignisobjekt nach dessen Erzeugung nur ein einziges Mal ausgeführt.
+ \item \textit{abstract public void onInit()}: Bevor ein Ereignisobjekt vom Simulator verwendet werden kann, muss es initialisiert werden. Diese Methode wird pro Ereignisobjekt nach dessen Erzeugung nur ein einziges Mal ausgeführt.
\item \textit{abstract public void onStart()}: Diese Methode wird jedes Mal ausgeführt, wenn das Ereignis eintritt. Sie stellt somit das Kernstück eines Ereignisses dar.
\end{itemize}
@@ -157,7 +157,7 @@ Des Weiteren werden folgende nicht-abstrakte Methoden der Klasse \textit{VSAbstr \begin{itemize}
\item \textit{public void log(String message)}: Diese Methode schreibt eine Lognachricht in das Simulationslogfenster.
\item \textit{public VSAbstractEvent getCopy()}: Diese Methode erstellt vom aktuellen Ereignis eine Kopie, auf die eine Referenz zurückgegeben wird. Alle Ereignisse, die kopiert werden können, müssen auch das Interface \textit{VSCopyableEvent} implementieren. Wenn ein Ereignis dies nicht tut und \textit{getCopy()} aufgerufen wird, wird die Ausnahme \textit{exceptions.VSEventNotCopyable} ausgel\"{o}st.
- \item \textit{public VSAbstractEvent getCopy(VSInternalProcess process)}: Diese Methode erstellt vom aktuellen Ereignis ebenfalls eine Kopie, mit dem Unterschied, dass das Ereignis einem anderen Prozess zugewiesen wird.
+ \item \textit{public VSAbstractEvent getCopy(VSAbstractProcess process)}: Diese Methode erstellt vom aktuellen Ereignis ebenfalls eine Kopie, mit dem Unterschied, dass das Ereignis einem anderen Prozess zugewiesen wird.
\end{itemize}
Jede Ereignisklasse hat außerdem Zugriff auf folgende Attribute, welche von \textit{VSAbstractEvent} geerbt werden:
@@ -171,7 +171,7 @@ Da \textit{VSAbstractEvent} die Klasse \textit{VSSerializablePrefs} erweitert, s \subsubsection{Beispielimplementierung eines Ereignisses}
-Im Folgenden wird als Beispiel die Implementierung des Prozessabsturzereignisses \textit{VSProcessCrashEvent} behandelt. Da die dazugehörige Klasse keine Attribute besitzt, verbleibt auch hier die \textit{initCopy}-Methode mit leerem Klassenrumpf. Aufgrund der Serializierbarkeit von Ereignisobjektten muss jede Ereignisklasse in \textit{onInit()} mit \textit{setClassname} den eigenen Klassennamen mitteilen. Bei der Deserialisierung von Ereignissen werden n\"{a}mlich Objekte anhand der Klassennamen dynamisch neu erstellt, wobei der Klassenname stets bekannt sein muss. In \textit{onStart()} wird das eigentliche Ereignis ausgeführt. Hier wird überprüft, ob der Prozess bereits abgestürzt ist und ggf. zum Absturz gebracht.
+Im Folgenden wird als Beispiel die Implementierung des Prozessabsturzereignisses \textit{VSProcessCrashEvent} behandelt. Da die dazugehörige Klasse keine Attribute besitzt, verbleibt auch hier die \textit{initCopy}-Methode mit leerem Methodenrumpf. Aufgrund der Serializierbarkeit von Ereignisobjekten muss jede Ereignisklasse in \textit{onInit()} mit \textit{setClassname} den eigenen Klassennamen mitteilen. Bei der Deserialisierung von Ereignissen werden n\"{a}mlich Objekte anhand der Klassennamen dynamisch neu erstellt, wobei der Klassenname stets bekannt sein muss. In \textit{onStart()} wird das eigentliche Ereignis ausgeführt. Hier wird überprüft, ob der Prozess bereits abgestürzt ist und ggf. zum Absturz gebracht.
\begin{code}
package events.implementations;
@@ -195,7 +195,7 @@ extends VSAbstractEvent implements VSCopyableEvent { }
\end{code}
-Der Task-Manager überprüft bereits, ob der Prozess abgestürzt ist oder nicht. Das f\"{u}hrt dazu, dass ein Ereignis bei einem abgestürztem Prozess gar nicht erst ausgeführt wird. Die einzige Ausnahme bildet ein Wiederbelebungsereignis (\text{VSProcessRecover}), welches auch dann ausgeführt wird, auch wenn der Prozess abgestürzt ist. Mit \textit{log} wird eine Nachricht (die über \textit{prefs} bezogen wird) in das Logfenster geschrieben.
+Der Task-Manager (s. Kap. 4.4.3.) überprüft bereits, ob der Prozess abgestürzt ist oder nicht. Das f\"{u}hrt dazu, dass ein Ereignis bei einem abgestürztem Prozess gar nicht erst ausgeführt wird. Die einzige Ausnahme bildet ein Wiederbelebungsereignis (\text{VSProcessRecover}), welches auch dann ausgeführt wird, auch wenn der Prozess abgestürzt ist. Mit \textit{log} wird eine Nachricht (die über \textit{prefs} bezogen wird) in das Logfenster geschrieben.
In der Datei \textit{events/VSRegisteredEvents.java} muss in der \textit{init}-Methode für jedes Ereignis ein Eintrag existieren. Die \textit{init}-Methode wird einmal beim Starten des Simulators ausgeführt:
@@ -223,7 +223,7 @@ Das Paket \textit{core.time} in Abbildung \ref{fig:PackageCoreTime}. stellt ledi \label{fig:PackageCoreTime}
\end{figure}
-In Abbildung \ref{fig:PackageCore}. ist das Paket \textit{core} dargestellt. Für jedes auszuführende Ereignis wird eine Instanz von \textit{VSTask} benötigt, welche die Ereigniseintrittszeit als Attribut abgpeichert. Die Instanz besitzt eine Referenz auf das Ereignisobjekt (\textit{VSAbstractEvent}) sowie das Prozessobjekt (\textit{VSInternalProcess}). Geplante \textit{VSTask}-Instanzen werden dem Task-Manager für eine spätere Ausführung übergeben.
+In Abbildung \ref{fig:PackageCore}. ist das Paket \textit{core} dargestellt. Für jedes auszuführende Ereignis wird eine Instanz von \textit{VSTask} benötigt, welche die Ereigniseintrittszeit als Attribut abgespeichert. Die Instanz besitzt eine Referenz auf das Ereignisobjekt (\textit{VSAbstractEvent}) sowie das Prozessobjekt (\textit{VSInternalProcess}). Geplante \textit{VSTask}-Instanzen werden dem Task-Manager für eine spätere Ausführung übergeben.
Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-Objekt erlaubt es, dass die gleiche \textit{VSAbstractEvent}-Instanz mehrmals im Task-Manager geplant werden kann. Ohne dieser Kapselung gäbe es für jedes Ereignis nur eine einzige mögliche Eintrittszeit. Von dieser Möglichkeit wird z.B. bei den Server- und Clientanfragen eines Protokollobjektes Gebrauch gemacht. Für jedes Protokoll kann der Anwender in einer Simulation beliebig viele Anfragen programmieren, wobei für jede Anfrage stets das selbe Protokollobjekt als Ereignis verwendet wird.
@@ -245,7 +245,7 @@ Der Task-Manager speichert anschließend die Nachrichtenempfangsereignisse in sei \begin{figure}[h]
\centering
\includegraphics[width=11.0cm]{images/wrapping}
- \caption{Gekapselte \textit{VSMessage} im \textit{VSMessageReceiveEvent}-Objekt}
+ \caption{Gekapseltes \textit{VSMessage}-Objekt}
\label{fig:Wrapping}
\end{figure}
@@ -300,7 +300,7 @@ Da der Simulator darauf ausgelegt wurde eigene Protokolle zu implementieren, wer \begin{itemize}
\setlength{\itemsep}{-2mm}
\item Einen öffentlichen (\textit{public}) Konstruktor. Der Konstruktor muss angeben, ob bei dem gegebene Protokoll der Client oder der Server die Anfragen startet.
- \item \textit{abstract public void onClientInit()}: Bevor das Protokollobjekt benutzt werden kann, muss es initialisiert werden. Diese Methode wird vor dem ersten Verwenden des Protokolls innerhalb einer Simulation ausgeführt. In der Regel werden hier Protokollvariablen unter Verwendung von \textit{VSPrefs} und Attribute der Protokollklasse initialisiert. Die hier initialisierten Protokollvariablen lassen sich vom Benutzer im Prozesseditor des jeweiligen Prozesses editieren.
+ \item \textit{abstract public void onClientInit()}: Bevor das Protokollobjekt benutzt werden kann, muss es initialisiert werden. Diese Methode wird vor dem ersten Verwenden des Protokolls innerhalb einer Simulation ausgeführt. In der Regel werden hier Protokollvariablen unter Verwendung von \textit{VSPrefs} und Attribute der Protokollklasse initialisiert.
\item \textit{abstract public void onClientReset()}: Diese Methode wird jedes Mal ausgeführt, wenn die Simulation zurückgesetzt wird.
\item \textit{abstract public void onClientStart()}: Diese Methode wird nur benötigt, wenn der Client immer die Anfragen startet. Diese Methode generiert in der Regel immer eine Clientanfrage, die via \textit{VSMessage}-Objekt an alle anderen beteiligten Prozesse verschickt wird.
\item \textit{abstract public void onClientRecv(VSMessage message)}: Diese Methode wird jedes Mal aufgerufen, wenn eine Servernachricht \textit{message} bei dem Client eintrifft.
@@ -329,7 +329,7 @@ Jede Protokollklasse erbt folgende Methoden von \textit{VSAbstractProtocol}, wel \item \textit{pubic final int getNumProcesses()}: Gibt die Gesamtzahl an der Simulation beteiligten Prozesse zurück.
\end{itemize}
-Bei der Implementierung von Protokollen kann zusätzlich auf die geerbten Attribute \textit{VSAbstractProcess process} und \textit{VSPrefs prefs} zugegriffen werden. Die verfügbare Methoden von \textit{VSPrefs} wurden bereits behandelt. über \textit{prefs} lassen sich alle globalen Simulationseinstellungen abrufen. Folgende Prozessmethoden dürfen auf \textit{process} aus dem Protokoll-API angewendet werden:
+Bei der Implementierung von Protokollen kann zusätzlich auf die geerbten Attribute \textit{VSAbstractProcess process} und \textit{VSPrefs prefs} zugegriffen werden. Die verfügbare Methoden von \textit{VSPrefs} wurden bereits behandelt. über \textit{prefs} lassen sich alle globalen Simulationseinstellungen abrufen. Folgende Prozessmethoden dürfen aus dem Protokoll-API auf \textit{process} angewendet werden:
\begin{itemize}
\setlength{\itemsep}{-2mm}
@@ -523,8 +523,7 @@ Hier werden alle Schritte zusammengefasst, die für die Erstellung eines eigenen \item Die Datei \textit{sources/events/VSRegisteredEvents.java} editieren, und in der \textit{init}-Methode folgende Zeile hinzufügen:
\begin{code}
registerEvent("protocols.implementations.VSMyProtocol",
- "Langer Name des Protokolls", // Langer Name
- "Neues Protokoll"); // Kurzer Name
+ "Neues Protokoll"); // Name
\end{code}
\item Mit dem Befehl \textit{ant compile} die Änderungen übernehmen und mit \textit{ant test} testen, ob der Simulator das Protokoll übernommen hat. Hierbei wird der Simulator direkt aus dem Quellverzeichnis gestartet. ``Neues Protokoll'' sollte nun im Ereigniseditor sichtbar sein und programmiert werden können.
\item Mit dem Befehl \textit{ant dist} das Archiv \textit{dist/lib/VS-Sim-Latest.jar} erstellen und verwenden.
@@ -534,7 +533,7 @@ Wenn eine Simulatorversion versucht eine abgespeicherte Simulation eines nicht i \section{GUI sowie Simulationsvisualisierung}
-Das Paket \textit{simulator} (s. Abb. \ref{fig:PackageProtocols}.) enthält die Implementierung der graphischen Benutzeroberfläche des Simulators. Einzigste Ausnahmen sind die Editorklassen in \textit{prefs.editors} sowie die Klasse \textit{utils.VSFrame} dar.
+Das Paket \textit{simulator} (s. Abb. \ref{fig:PackageProtocols}.) enthält die Implementierung der graphischen Benutzeroberfläche des Simulators. Einzigste Ausnahmen sind die Editorklassen in \textit{prefs.editors} sowie die Klasse \textit{utils.VSFrame}.
Beim Starten des Simulators wird die \textit{main}-Methode, welche sich in \textit{VSMain} befindet, aufgerufen. Sie instantiiert ein \textit{VSDefaultPrefs}-Objekt, in welchem alle Standardeinstellungen des Simulators definiert sind. Anschließend wird ein \textit{VSSimulatorFrame} erzeugt, welches ein Simulatorfenster (s. Abb. \ref{fig:NeuesFenster}.) implementiert. Das Simulatorfenster erstellt für jede neue Simulation jeweils ein Objekt der Klasse \textit{VSSimulator}, wobei jede Simulation im Simulationsfenster einen eigenen Tab besitzt (s. Abb. \ref{fig:NeuErstellteSimulation}., unten links). Jede Simulation besitzt dabei eine eigene Simulationsnummer. Jedes \textit{VSSimulator}-Objekt greift auf die Klasse \textit{VSSimulatorVisualization} zurück, welche die Visualisierung der Simulation realisiert (s. Abb. \ref{fig:Visualisierung}.) .
@@ -545,7 +544,7 @@ Beim Starten des Simulators wird die \textit{main}-Methode, welche sich in \text \label{fig:PackageProtocols}
\end{figure}
-\textit{VSSimulatorVisualization} greift auf Java's Grafikbibliothek Java2D (siehe \cite{Java2d}, \cite{Java2DAPI}, \cite{Games}) zu und ist zur Optimierung der Performance mit dem Simulationsverlauf stark verzahnt. Klassenattribute, die von Simulationseinstellungen und den Fenstergr\"{o}ßen abhängigig sind, werden so nur dann neu neu berechnet wenn dies erforderlich ist.
+\textit{VSSimulatorVisualization} greift auf Java's Grafikbibliothek Java2D (siehe \cite{Java2d}, \cite{Java2DAPI}, \cite{Games}) zu und ist zur Optimierung der Performance mit dem Simulationsverlauf stark verzahnt. Klassenattribute, die von Simulationseinstellungen und den Fenstergr\"{o}ßen abhängigig sind, werden so nur dann neu berechnet wenn dies erforderlich ist.
Die Klasse \textit{VSMenuItemStates} wird für die Synchronisierung der graphischen Elemente des GUI's mit dem Status der Simulation verwendet. Abhängig vom Simulationsstatus kann der Benutzer bestimmte Aktionen entweder durchführen oder nicht. Zum Beispiel kann eine Simulation nur pausiert werden, wärend sie abgespielt wird. Alle hier möglichen Aktionen sind bereits aus Kapitel 2.1. bekannt.
@@ -560,7 +559,7 @@ Der Simulator soll auf die Millisekunde genau simulieren k\"{o}nnen und dabei so \begin{itemize}
\item Das Zeichnen der Visualisierung benötigt pro Aktualisierung einige Millisekunden. Hier werden ständig mathematische Berechnungen wie z.B. die Berechnung einer Nachrichtenlinie oder die automatische Skalierung des Diagramms durchgef\"{u}hrt.
\item Das Neuberechnen der Simulation benötigt pro Aktualisierung einige Millisekunden. Hier arbeitet insbesondere der Task-Manager, welcher überprüft, ob Ereignisse auszuführen sind.
- \item Jeder simulierte Prozess sollte mit der selben Geschwindigkeit fortschreiten, und dies auf jedem Betriebssystem und auf jeder Architektur. Da Threads auf Betriebssystemebene implementiert sind sind Java-Threads nicht komplett plattformunabhängig. Dadurch kann das Verhalten auf je nach Betriebssystem und Architekturen variieren. Insbesondere übernimmt das Betriebssystem die Entscheidung, wann welcher Thread arbeiten darf.
+ \item Jeder simulierte Prozess sollte mit der selben Geschwindigkeit fortschreiten, und dies auf jedem Betriebssystem und auf jeder Architektur. Da Threads auf Betriebssystemebene implementiert sind sind Java-Threads nicht komplett plattformunabhängig. Dadurch kann das Verhalten je nach Betriebssystem und Architekturen variieren. Insbesondere übernimmt das Betriebssystem die Entscheidung, wann welcher Thread arbeiten darf.
\item Die Simulationszeit wird stets in Millisekunden angegeben und sie wird intern in einer \textit{long}-Variable abgespeichert. Somit kann eine Simulationszeit immer nur den Wert einer ganze Zahl betragen. Berechnungsrundungsfehler durch \textit{sim.clock.speed} (s. Kap. 2.4.2.) müssen berücksichtigt werden.
\item Der Simulator soll die komplette CPU des Anwender-Computers nicht konstant auslasten.
\end{itemize}
@@ -581,9 +580,9 @@ for (i = t; i < t + v + p && i < e; i++) \item Bei Punkt 2 mit neuer Startzeit $t := t + v + p$ weitermachen.
\end{enumerate}
-Zus\"{a}tzlich muss noch die Simulationsvariable \textit{sim.clock.speed} ber\"{u}cksichtigt werden. Sie wurde zur verbesserten Übersicht im obigen Algorithmus nicht extra angegeben. Intern speichert der Simulator jeweils die echte Zeit und die Simulationszeit. Die verstrichenen echten Zeiten werden dabei ständig gemessen und anschließend mit \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Die Rundungsfehler werden pro Durchgang in einer \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert. Wenn der Betrag der Rundungsfehler $>= 1$ ist, dann wird davon der gesamte Werteanteil in der Simulationszeit berücksichtigt. F\"{u}r jede lokale Prozesszeit sowie der dazugeh\"{o}rigen lokalen Uhrabweichung wird \"{a}hnlich verfahren.
+Zus\"{a}tzlich muss noch die Simulationsvariable \textit{sim.clock.speed} ber\"{u}cksichtigt werden. Sie wurde zur verbesserten Übersicht im obigen Algorithmus nicht extra angegeben. Intern speichert der Simulator jeweils die echte Zeit und die Simulationszeit. Die verstrichenen echten Zeiten werden dabei ständig gemessen und anschließend mit \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Die Rundungsfehler werden pro Durchgang in einer \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert. Wenn der Betrag der Rundungsfehler $>= 1$ ist, dann wird davon der ganzteilige Werteanteil in der Simulationszeit berücksichtigt. F\"{u}r jede lokale Prozesszeit sowie der dazugeh\"{o}rigen lokalen Uhrabweichung wird \"{a}hnlich verfahren.
-Jede Simulation besitzt somit seinen eigenen Simulationsthread. Des Weiteren gibt es noch den Java Swing-Thread (s. \cite{Swing}), der für das GUI und f\"{u}r die Anwenderinteraktion zuständig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen, weswegen die Behandlund derAnwendereingriffe synchronisiert wurde.
+Jede Simulation besitzt somit seinen eigenen Simulationsthread. Des Weiteren gibt es noch den Java Swing-Thread (s. \cite{Swing}), der für das GUI und f\"{u}r die Anwenderinteraktion zuständig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen, weswegen die Behandlung der Anwendereingriffe synchronisiert wurde.
\section{Serialisierung und Deserialisierung von Simulationen}
@@ -596,7 +595,7 @@ Da nicht alle Daten f\"{u}r die Speicherung einer Simulation relevant sind, wird \item \textit{public void deserialize(VSSerialize serialize, ObjectInputStream ois)}: Diese Methode wird bei jedem Deserialisierungsvorgang aufgerufen (Laden einer Simulation).
\end{itemize}
-Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einem Dateistream auch ein \textit{VSSerialize}-Objekt als \"{U}bergabeparameter. Für jeden Serialisierungsvorgang wird zuerst ein Objekt der Klasse \textit{VSSerialize} erstellt. Eine zu serialisierende Simulation besteht aus einer Vielzahl von einander abhängigen Objekten. Jedes Objekt kann dabei Referenzen auf andere Objekte besitzen. Würde jedes Objekt komplett serialisiert werden, so würden Objekte, auf denen mehrere Referenzen existierten, in mehrfacher Ausführung behandelt werden. Bei Kreisverweisen (Objekt A referenziert Objekt B welches ebenfalls eine Referenz auf Objetkt A besitzt) würde die Serialisierung sogar in einer Endlosschleife enden. \textit{VSSerialize} hilft hierbei dies zu vermeiden und merkt sich Informationen von allen bereits serialisierten Objekten, so dass jedes Objekt genau einmal serialisiert wird. Bei der Deserialisierung hilft eine die Klasse \textit{VSSerialize} dabei, alle Objekte wieder mit den richtigen Referenzen auszustatten.
+Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einem Dateistream auch ein \textit{VSSerialize}-Objekt als \"{U}bergabeparameter. Für jeden Serialisierungsvorgang wird zuerst ein Objekt der Klasse \textit{VSSerialize} erstellt. Eine zu serialisierende Simulation besteht aus einer Vielzahl von einander abhängigen Objekten. Jedes Objekt kann dabei Referenzen auf andere Objekte besitzen. Würde jedes Objekt komplett serialisiert werden, so würden Objekte, auf denen mehrere Referenzen existierten, in mehrfacher Ausführung behandelt werden. Bei Kreisverweisen (Objekt A referenziert Objekt B welches ebenfalls eine Referenz auf Objetkt A besitzt) würde die Serialisierung sogar in einer Endlosschleife enden. \textit{VSSerialize} hilft hierbei dies zu vermeiden und merkt sich Informationen von allen bereits serialisierten Objekten, so dass jedes Objekt genau einmal serialisiert wird. Bei der Deserialisierung hilft die Klasse \textit{VSSerialize} dabei, alle Objekte wieder mit den richtigen Referenzen auszustatten.
\begin{figure}[h]
\centering
@@ -650,8 +649,8 @@ Es wurden noch nicht die Klassen der Pakete \textit{utils} (s. Abb. \ref{fig:Pac \item \textit{VSInfoArea}: Ist für die Textanzeige in \textit{VSAboutFrame} zuständig.
\item \textit{VSClassLoader}: Diese Klasse wird für die automatische Instanzierung von Ereignisobjekten benötigt, wenn dem Simulator lediglich die Klassennamen (aus \textit{events.VSRegisteredEvents}) bekannt sind.
\item \textit{VSHelper}: In dieser Klasse befinden sich statische Helfermethoden, die in keine andere Klasse gehören.
- \item \textit{VSPriorityQueue}: Diese Klasse wird für das Verwalten von \textit{core.VSTask}-Objekte im Task-Manager benötigt. \textit{VSPriorityQueue} passt die Prioritäts-Warteschlange aus der Java-Standardbibliothek den Anforderungen des Simulators an.
- \item \textit{VSRandom}: Wird für Zufallsereignisse benötigt. Jedes Prozessobjekt besitzt einen solchen eigenen Pseudozufallsgenerator. Diese Klasse setzt gleichzeitig einen eigenen Seed basierend auf der lokalen Systemzeit und anderer Berechnungen fest.
+ \item \textit{VSPriorityQueue}: Diese Klasse wird für das Verwalten von \textit{core.VSTask}-Objekte im Task-Manager benötigt.
+ \item \textit{VSRandom}: Wird für Zufallsereignisse benötigt. Jedes Prozessobjekt besitzt einen solchen eigenen Pseudozufallsgenerator. Diese Klasse setzt gleichzeitig einen eigenen Seed basierend auf der lokalen Systemzeit und anderer Zahlen fest.
\item \textit{VSTupel}: Diese Klasse ist eine Implementierung eines einfach aufgebauten 3-Tupel Datentyps. Alle 3 Elemente können von einem anderen Typ sein, was mit Hilfe der Java-Generics verwirklicht wurde. \textit{VSTupel} wird von den Editorklassen für die Generierung von GUI-Elementen benötigt.
\end{itemize}
@@ -683,12 +682,12 @@ Die \textit{main}-Methode befindet sich in der Klasse \textit{simulator.VSMain}. \item Alle Namen von Klassen und Interfaces beginnen mit großen Buchstaben, während alle Variablen-, Methoden- und Attributnamen mit kleinen Buchstaben beginnen. Namen finaler Variablen und Attribute bzw. Konstanten sind komplett in Großbuchstaben gehalten.
\item Alle Quelltext-Dateien besitzen einen Header, der Informationen der verwendeten Lizenz angibt.
\item Alle Quelltext-Dateien sind vollständig mit Javadoc dokumentiert.
- \item Der komplette Quelltext inklusive Dokumentation wird in englischer Sprache verfasst.
+ \item Der komplette Quelltext inklusive Dokumentation ist in englischer Sprache verfasst.
\item Eine Quelltext-Datei hat eine maximale Zeilenlänge von 80 Zeichen, was der Standardbreite eines UNIX-Terminals entspricht. Eine Ausnahme stellt die Klasse \textit{prefs.VSDefaultPrefs} dar, denn hier befinden sich auch längere Texte die in Strings abgespeichert werden müssen.
\item Es werden zuerst Klassen aus der Java-Standardbibliothek importiert, bevor Klassen aus dem VS-Simulator selbst importiert werden.
\item Für die Einrückung des Quelltextes wird das Tool \textit{astyle} mit den Aufrufparametern \textit{--style=java --mode=java} verwendet. Hierbei wird eine Einrückungslänge von 4 Zeichen verwendet.
\item Namen aller Klassen und Interfaces tragen als Präfix stets \textit{VS}. Die Abkürzung VS steht hierbei für Verteilte Systeme.
- \item Namen abstrakter Klassen tragen als Präfix stets \textit{VSAbstract}.
+ \item Namen abstrakter Klassen tragen als Präfix stets \textit{VSAbstract} (z.B. \textit{VSAbstractEditor}).
\item Namen aller Protokollklassen tragen als Postfix \textit{Protocol} (z.B. \textit{VSPingPongProtocol}).
\item Namen aller Ereignisklassen die keine Protokolle implementieren, tragen als Postfix \textit{Event} (z.B. \textit{VSProcessCrashEvent}).
\item Namen aller dejenigen Klassen die ein Fenster implementieren, tragen als Postfix \textit{Frame} (z.B. \textit{VSSimulatorFrame}).
diff --git a/LaTeX/chapters/protokolle.tex b/LaTeX/chapters/protokolle.tex index d214f42..accabff 100644 --- a/LaTeX/chapters/protokolle.tex +++ b/LaTeX/chapters/protokolle.tex @@ -5,7 +5,7 @@ Im Programmverzeichnis des Simulators befindet sich das Verzeichnis \textit{save \section{Beispiel (Dummy) Protokoll}
-Das Dummy-Protokoll dient lediglich als Vorlage für die Erstellung eigener Protokolle. Bei der Verwendung des Dummy-Protokolls werden bei Auftreten von Ereignissen (s. Kap. 2.2.3.) lediglich Lognachrichten ausgegeben. Es werden aber keine weiteren Aktionen ausgeführt.
+Das Dummy-Protokoll dient lediglich als Vorlage für die Erstellung eigener Protokolle. Bei der Verwendung des Dummy-Protokolls werden bei Auftreten von Ereignissen lediglich Lognachrichten ausgegeben. Es werden aber keine weiteren Aktionen ausgeführt.
\newpage
\section{Das Ping-Pong Protokoll \small{\textit{(ping-pong.dat, ping-pong-sturm.dat)}}}
@@ -61,6 +61,9 @@ Werden die Ereignisse wie in Tabelle \ref{tb:PingPongSturmTasks}. vorgegeben, so \label{tb:PingPongSturmTasks}
\end{table}
+\newpage
+\section{Das Broadcast Protokoll \small{\textit{(broadcast.dat)}}}
+
\begin{table}
\centering
\fbox{
@@ -87,9 +90,6 @@ Werden die Ereignisse wie in Tabelle \ref{tb:PingPongSturmTasks}. vorgegeben, so \label{tb:BroadcastSturmTasks}
\end{table}
-\newpage
-\section{Das Broadcast Protokoll \small{\textit{(broadcast.dat)}}}
-
\begin{figure}[h]
\centering
\fbox{\includegraphics[width=10cm]{images/ss-protokoll-broadcast-sturm}}
@@ -101,10 +101,10 @@ Das Broadcast Protokoll verhält sich ähnlich wie das Ping-Pong Protokoll. Der Un In diesem Fall wird nicht zwischen Client und Server unterschieden, so dass bei der Ankunft einer Nachricht jeweils die gleiche Aktion durchgef\"{u}hrt wird. Somit lässt sich, unter Verwendung mehrerer Prozesse (s. Abb. \ref{fig:BroadcastSturmProto}.) ein Broadcast erzeugen. P1 ist der Client und startet je eine Anfrage nach \textit{0ms} und \textit{2500ms}. Die Simulationsdauer beträgt hier genau \textit{5000ms}. Da ein Client nur Servernachrichten und ein Server nur Clientnachrichten empfangen kann, ist in dieser Simulation jeder Prozess (s. Tabelle \ref{tb:BroadcastSturmTasks}) gleichzeitig Server und Client.
-
+\newpage
\section{Das Protokoll zur internen Synchronisierung in einem synchronen System \small{\textit{(int-sync.dat)}}}
-Bisher wurden nur Protokolle dargestellt, in denen die beteiligten Prozesse keine Uhrabweichungen hatten. Das Protokoll zur internen Synchronisierung ist ein Protokoll zur Synchronisierung der lokalen Prozesszeit, welches beispielsweise angewendet werden kann, wenn eine Prozesszeit aufgrund einer Uhrabweichung falsch geht. Wenn der Client seine (falsche) lokale Prozesszeit $t_c$ mit einem Server synchronisieren möchte, so schickt er ihm eine Clientanfrage. Der Server schickt als Antwort seine eigene lokale Prozesszeit $t_s$ zurück, womit der Client eine neue und genauere Prozesszeit f\"{u}r sich berechnen kann. Die neue Prozesszeit wird wie folgt berechnet:
+Bisher wurden nur Protokolle dargestellt, in denen die beteiligten Prozesse keine Uhrabweichungen hatten. Das Protokoll zur internen Synchronisierung ist ein Protokoll zur Synchronisierung der lokalen Prozesszeit, welches beispielsweise angewendet werden kann, wenn eine Prozesszeit aufgrund einer Uhrabweichung falsch geht. Wenn der Client seine (falsche) lokale Prozesszeit $t_c$ mit einem Server synchronisieren möchte, so schickt er ihm eine Clientanfrage. Der Server schickt als Antwort seine eigene lokale Prozesszeit $t_s$ zurück, womit der Client eine neue und genauere Prozesszeit f\"{u}r sich berechnen kann.
\begin{figure}[h]
\centering
@@ -121,7 +121,7 @@ Hier (s. Abb. \ref{fig:TimeSyncProto}.) stellt P1 den Client und P2 den Server d Somit wird die lokale Zeit von P1, mit einem Fehler von $< \frac{1}{2} (t'_{max} - t'_{min})$, mit der Serverzeit synchronisiert (siehe \cite{Vorlesung}).
-Im Beispiel hat der Clientprozess als Uhrabweichung den Wert \textit{0.1} und der Server hat als Uhrabweichung den Wert \textit{0.0} konfiguriert. Der Client startet, wie in Tabelle \ref{tb:InterneSyncTasks}. angegeben, nach \textit{0ms}, \textit{5000ms} und \textit{10000ms} seiner lokalen Prozesszeit jeweils eine Clientanfrage. In der Abbildung lässt sich erkennen, dass die zweite und die dritte Anfrage nicht synchron zu der globalen Zeit (vgl. Sekunden-Zeitgatter, Abbildung \ref{tb:TimeSyncProto)}.) gestartet wurden, was auf die Uhrabweichung von P1 zurückzuführen ist. Nach Simulationsende ist die Zeit von P1 bis auf \textit{15000ms} - \textit{15976ms} = \textit{-976ms} synchronisiert.
+Im Beispiel hat der Clientprozess als Uhrabweichung den Wert \textit{0.1} und der Server hat als Uhrabweichung den Wert \textit{0.0} konfiguriert. Der Client startet, wie in Tabelle \ref{tb:InterneSyncTasks}. angegeben, nach \textit{0ms}, \textit{5000ms} und \textit{10000ms} seiner lokalen Prozesszeit jeweils eine Clientanfrage. In der Abbildung lässt sich erkennen, dass die zweite und die dritte Anfrage nicht synchron zu der globalen Zeit gestartet wurden, was auf die Uhrabweichung von P1 zurückzuführen ist. Nach Simulationsende ist die Zeit von P1 bis auf \textit{15000ms} - \textit{15976ms} = \textit{-976ms} synchronisiert.
\begin{table}
\centering
@@ -149,7 +149,7 @@ Dieses Protokoll verwendet folgende zwei clientseitige Variablen, die in den Pro \item \textbf{Max. Übertragungszeit} \textit{(Long: 2000)}: Gibt den Wert $t'_{max}$ in Millisekunden an
\end{itemize}
-$t'_{min}$ und $t'_{max}$ sind die bei den Protokollberechnungen verwendeten Werte. Sie können sich allerdings von den tatsächlichen Nachrichtenübertragungszeiten $t_{min}$ und $t_{max}$ (s. Kap. 2.4.3.) unterscheiden. Somit lassen sich auch Szenarien simulieren, in denen das Protokoll falsch eingestellt wurde und wobei der Zeitsynchronisierung große Fehler auftreten können.
+$t'_{min}$ und $t'_{max}$ sind die bei den Protokollberechnungen verwendeten Werte. Sie können sich allerdings von den tatsächlichen Nachrichtenübertragungszeiten $t_{min}$ und $t_{max}$ (s. Kap. 2.4.3.) unterscheiden. Somit lassen sich auch Szenarien simulieren, in denen das Protokoll falsch eingestellt wurde und wo bei der Zeitsynchronisierung große Fehler auftreten können.
\newpage
\section{Christians Methode zur externen Synchronisierung \small{\textit{(ext-vs-int-sync.dat)}}}
@@ -161,9 +161,9 @@ $t'_{min}$ und $t'_{max}$ sind die bei den Protokollberechnungen verwendeten Wer \label{fig:TimeSync2Proto}
\end{figure}
-Ein weiteres Protokoll für die Synchronisierung von Uhrzeiten funktioniert nach der Christians Methode zur externen Synchronisierung. Die Christians Methode benutzt die RTT (Round Trip Time) $t_{rtt}$, um die Übertragungszeit von einzelnen Nachrichten zu approximieren.
+Ein weiteres Protokoll für die Synchronisierung von Uhrzeiten funktioniert nach der Christians Methode zur externen Synchronisierung. Die Christians Methode benutzt die RTT (Round Trip Time), um die Übertragungszeit von einzelnen Nachrichten zu approximieren.
-Wenn der Client seine lokale Zeit $t_c$ bei einem Server synchronisieren möchte, so verschickt er eine Anfrage, und misst dabei die dazugehörige RTT $t_{rtt}$ bis zur Ankunft der Serverantwort. Die Serverantwort beinhaltet die lokale Prozesszeit $t_s$ des Servers von dem Zeitpunkt an dem der Server die Antwort verschickt. Der Client berechnet dann seine lokale Zeit neu mit:
+Wenn der Client seine lokale Zeit $t_c$ bei einem Server synchronisieren möchte, so verschickt er eine Anfrage, und misst dabei bis zur Ankunft der Serverantwort die dazugehörige RTT $t_{rtt}$. Die Serverantwort beinhaltet die lokale Prozesszeit $t_s$ des Servers von dem Zeitpunkt an dem der Server die Antwort verschickte. Der Client berechnet dann seine lokale Zeit neu mit:
\begin{equation*}
t_c := t_s + \frac{1}{2} t_{rtt}
@@ -197,6 +197,7 @@ Aus Abbildung \ref{fig:TimeSync2Proto}. ist ersichtlich, dass nach Ablauf der Si \label{tb:InterneSync2Tasks}
\end{table}
+\newpage
\section{Der Berkeley Algorithmus zur internen Synchronisierung \small{\textit{(berkeley.dat)}}}
\begin{figure}[h]
@@ -206,7 +207,7 @@ Aus Abbildung \ref{fig:TimeSync2Proto}. ist ersichtlich, dass nach Ablauf der Si \label{fig:BerkeleyProto}
\end{figure}
-Der Berkeley Algorithmus zur internen Synchronisierung ist eine weitere Möglichkeit lokale Uhrzeiten abzugleichen. Dies ist das erste Protokoll, wo der Server die Anfragen startet. Der Server fungiert gewissermaßen Koordinator des Protokolls. Die Clientprozesse sind somit passiv und müssen warten, bis eine Serveranfrage eintrifft. Hierbei muss der Server wissen, welche Clientprozesse an dem Protokoll teilnehmen, was sich in den Protokolleinstellungen des Servers einstellen lässt (s. Kap. 2.4.3.).
+Der Berkeley Algorithmus zur internen Synchronisierung ist eine weitere Möglichkeit lokale Uhrzeiten abzugleichen. Dies ist das erste Protokoll, wo der Server die Anfragen startet. Der Server fungiert gewissermaßen als Koordinator des Protokolls. Die Clientprozesse sind somit passiv und müssen warten, bis eine Serveranfrage eintrifft. Hierbei muss der Server wissen, welche Clientprozesse an dem Protokoll teilnehmen, was sich in den Protokolleinstellungen des Servers einstellen lässt.
Wenn der Server seine lokale Zeit $t_s$ und auch die Prozesszeiten $t_i$ der Clients ($i = 1, ..., n$) synchronisieren möchte, so verschickt er eine Serveranfrage. $n$ sei hierbei die Anzahl beteiligter Clients. Die Clients senden dann ihre lokalen Prozesszeiten in einer Nachricht zurück zum Server. Der Server hat dabei die RTTs $r_i$ bis zur Ankunft aller Clientantworten gemessen.
@@ -252,6 +253,7 @@ Dieses Protokoll verwendet folgende serverseitige Variable, die in den Prozessei \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Berkeley Clientprozesse, mit denen der Berkeley Server die Zeit synchronisieren soll. Das Protokoll funktioniert nicht, wenn hier eine PID angegeben wird die nicht existiert oder die das Berkeley Protokoll clientseitig nicht unterstützt. In diesem Fall würde ewig auf eine (fehlende) Clientantwort gewartet werden.
\end{itemize}
+\newpage
\section{Das Ein-Phasen Commit Protokoll \small{\textit{(one-phase-commit.dat)}}}
\begin{figure}[h]
@@ -263,7 +265,7 @@ Dieses Protokoll verwendet folgende serverseitige Variable, die in den Prozessei Das Ein-Phasen Commit Protokoll ist dafür gedacht beliebig vielen Clients zu einer Festschreibung zu bewegen. Im realen Leben könnte dies beispielsweise das Erstellen oder Löschen einer Datei sein, von der auf jedem Client eine lokale Kopie existiert. Der Server ist der Koordinator und auch derjenige, der einen Festschreibewunsch initiiert. Hierbei verschickt der Server periodisch so oft den Festschreibewunsch, bis er von jedem Client eine Bestätigung erhalten hat. Hierf\"{u}r m\"{u}ssen f\"{u}r den Server die PIDs aller beteiligten Clientprozesse sowie ein Wecker f\"{u}r erneutes Versenden des Festschreibewunsches konfiguriert werden.
-Die programmierten Ereignisse des Beispiels auf (s. Abb. \ref{fig:OnePhaseCommitProto}.) sind in Tabelle \ref{tb:OnePhaseCommitTasks}. aufgelistet. P1 und P3 simulieren jeweils einen Client und P2 den Server. Damit die Simulation mehrere Festschreibewünsche verschickt, stürzt in der Simulation P1 nach \textit{1000ms} ab und nach \textit{5000ms} steht er wieder zur Verfügung. Die ersten beide Festschreibewünsche erreichen dadurch P1 nicht und erst der dritte Versuch verläuft erfolgreich. Bevor die Bestätigung von P1 bei P2 eintrifft, läuft jedoch der Wecker erneut ab, so dass ein weiterer Festschreibewunsch versendet wird. Da P1 und P3 jeweils schon eine Bestätigung verschickt haben, wird diese Festschreibewunschnachricht ignoriert. Jeder Client bestätigt auf einen Festschreibewunsch nur ein einziges Mal.
+Die programmierten Ereignisse des Beispiels auf (s. Abb. \ref{fig:OnePhaseCommitProto}.) sind in Tabelle \ref{tb:OnePhaseCommitTasks}. aufgelistet. P1 und P3 simulieren jeweils einen Client und P2 den Server. Damit die Simulation mehrere Festschreibewünsche verschickt, stürzt in der Simulation P1 nach \textit{1000ms} ab und nach \textit{5000ms} steht er wieder zur Verfügung. Die ersten beiden Festschreibewünsche erreichen dadurch P1 nicht und erst der dritte Versuch verläuft erfolgreich. Bevor die Bestätigung von P1 bei P2 eintrifft, läuft jedoch der Wecker erneut ab, so dass ein weiterer Festschreibewunsch versendet wird. Da P1 und P3 jeweils schon eine Bestätigung verschickt haben, wird diese Festschreibewunschnachricht ignoriert. Jeder Client bestätigt auf einen Festschreibewunsch nur ein einziges Mal.
\begin{table}
\centering
@@ -293,6 +295,7 @@ Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesse \end{itemize}
+\newpage
\section{Das Zwei-Phasen Commit Protokoll \small{\textit{(two-phase-commit.dat)}}}
\begin{figure}[h]
@@ -463,21 +466,9 @@ Die folgende Clientvariable kann unter den Prozesseinstellungen unter dem Punkt \end{table}
+\newpage
\section{Der ungenügende (Basic) Multicast \small{\textit{(basic-multicast.dat)}}}
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-basic-multicast}}
- \caption{Das Basic-Multicast Protokoll}
- \label{fig:BasicMulticastProto}
-\end{figure}
-
-Das Basic-Multicast Protokoll ist sehr einfach aufgebaut. Im Beispiel in Abbildung \ref{fig:BasicMulticastProto}. sind P1 und P3 Server und P2 der Client. Bei diesem Protokoll startet der Client immer die Anfrage, welche bei diesem Protokoll eine einfache Multicast-Nachricht darstellt. Die Basic-Multicast Server dienen dabei lediglich zum Empfang einer Nachricht. Es werden keine Bestätigungen verschickt. Wie in Tabelle \ref{tb:BasicMulticastTasks}. aufgeführt verschickt P2 alle \textit{2500ms} jeweils eine Multicast-Nachricht, die alle voneinander völlig unabhängig sind.
-
-P1 kann jedoch erst nach \textit{2500ms} Multicast-Nachrichten empfangen, da er vorher das Protokoll nicht unterstützt während P3 von \textit{3000ms} bis \textit{6000ms} abgestürzt ist und in dieser Zeit auch keine Nachrichten empfangen kann. In diesem Beispiel ist P1 ein Server, der erst sp\"{a}ter ans Netz angeschlossen wird. Da die Einstellung ``Nur relevante Nachrichten anzeigen'' aktiviert ist, wird die erste Multicast-Nachricht von P2 an P1 nicht dargestellt. Bei jedem Prozess wurde die Nachrichtenverlustwahrscheinlichkeit auf \textit{30} Prozent gestellt, so dass alle in dieser Simulation verschickten Nachrichten mit einer Wahrscheinlichkeit von \textit{30} Prozent ausfallen.
-
-In diesem Beispiel ging die 3. Multicast-Nachricht auf den Weg zu P3- und die 5. sowie 6. Nachricht auf den Weg zu P1 verloren. Lediglich die 4. Multicast-Nachricht hat beide Ziele erreicht.
-
\begin{table}
\centering
\fbox{
@@ -501,7 +492,20 @@ In diesem Beispiel ging die 3. Multicast-Nachricht auf den Weg zu P3- und die 5. \label{tb:BasicMulticastTasks}
\end{table}
+\begin{figure}[h]
+ \centering
+ \fbox{\includegraphics[width=10cm]{images/ss-protokoll-basic-multicast}}
+ \caption{Das Basic-Multicast Protokoll}
+ \label{fig:BasicMulticastProto}
+\end{figure}
+
+Das Basic-Multicast Protokoll ist sehr einfach aufgebaut. Im Beispiel in Abbildung \ref{fig:BasicMulticastProto}. sind P1 und P3 Server und P2 der Client. Bei diesem Protokoll startet der Client immer die Anfrage, welche bei diesem Protokoll eine einfache Multicast-Nachricht darstellt. Die Basic-Multicast Server dienen dabei lediglich zum Empfang einer Nachricht. Es werden keine Bestätigungen verschickt. Wie in Tabelle \ref{tb:BasicMulticastTasks}. aufgeführt verschickt P2 alle \textit{2500ms} jeweils eine Multicast-Nachricht, die alle voneinander völlig unabhängig sind.
+P1 kann jedoch erst nach \textit{2500ms} Multicast-Nachrichten empfangen, da er vorher das Protokoll nicht unterstützt während P3 von \textit{3000ms} bis \textit{6000ms} abgestürzt ist und in dieser Zeit auch keine Nachrichten empfangen kann. In diesem Beispiel simuliert P1 ein Server, der erst sp\"{a}ter ans Netz angeschlossen wird. Da die Einstellung ``Nur relevante Nachrichten anzeigen'' aktiviert ist, wird die erste Multicast-Nachricht von P2 an P1 nicht dargestellt. Bei jedem Prozess wurde die Nachrichtenverlustwahrscheinlichkeit auf \textit{30} Prozent gestellt, so dass alle in dieser Simulation verschickten Nachrichten mit einer Wahrscheinlichkeit von \textit{30} Prozent ausfallen.
+
+In diesem Beispiel ging die 3. Multicast-Nachricht auf den Weg zu P3- und die 5. sowie 6. Nachricht auf den Weg zu P1 verloren. Lediglich die 4. Multicast-Nachricht hat beide Ziele erreicht.
+
+\newpage
\section{Das zuverlässige (Reliable) Multicast Protokoll \small{\textit{(reliable-multicast.dat)}}}
\begin{figure}[h]
@@ -609,7 +613,6 @@ Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesse & & Boolean: isMulticast=true\\
\hline
005952 & 1 & Nachricht erhalten; ID: 283; Protokoll: Reliable Multicast\\
-\hline
\end{tabular}
}
\caption{Auszug aus dem Logfenster des Reliable-Multicast Beispiels}
@@ -704,7 +707,7 @@ Es wird also stets die größere Lamportzeit vom Sender- und Empfängerprozess verw \label{fig:Vektorzeit}
\end{figure}
-Mit aktivem Vektorzeit-Schalter werden alle Vektor-Zeitstempel angezeigt (s. Abb. \ref{fig:Vektorzeit}.). Wie beim Lamport-Zeitstempel wird auch hier jeder Nachricht der aktuelle Vektor-Zeitstempel des Senderprozesses beigefügt. Bei $n$ beteiligten Prozessen hat der Vektor-Zeitstempel $v$ die Größe $n$. Somit gibt es für jeden beteiligten Prozess $i$ einen eigenen Index $i$. Mit $v(i)$ kann jeder Prozess auf seinen lokalen Eintrag zugreifen. Wenn $v$ der Vektor-Zeitstempel des Empfängerprozesses $j$ ist und $w$ der Vektor-Zeitstempel des Senderprozesses ist, dann wird der neue lokale Vektor-Zeitstempel wie folgt neu berechnet:
+Mit aktivem Vektorzeit-Schalter werden alle Vektor-Zeitstempel angezeigt (s. Abb. \ref{fig:Vektorzeit}.). Wie beim Lamport-Zeitstempel wird auch hier jeder Nachricht der aktuelle Vektor-Zeitstempel des Senderprozesses beigefügt. Bei $n$ beteiligten Prozessen hat der Vektor-Zeitstempel $v$ die Größe $n$. Somit gibt es für jeden beteiligten Prozess $i$ einen eigenen Index $i$. Mit $v(i)$ kann jeder Prozess auf seinen lokalen Eintrag zugreifen. Wenn $v$ der Vektor-Zeitstempel des Empfängerprozesses $j$ ist und $w$ der Vektor-Zeitstempel des Senderprozesses ist, dann wird der neue lokale Vektor-Zeitstempel vom Prozess $j$ wie folgt neu berechnet:
\textbf{Pseudo-Code}
@@ -724,8 +727,9 @@ Im Beispiel (vgl. Abbildung \ref{fig:Vektorzeit}.) hat P1 \textit{(8,10,6)}, P2 Wenn während einer Simulation Prozesse entfernt- oder neue Prozesse hinzugefügt werden, so passt sich die Größe der Vektor-Zeitstempel aller anderen Prozesse automatisch der Gesamtzahl der Prozesse an.
-Wie bereits beschrieben gibt es in den Simulationseinstellungen die boolschen Variablen ``Lamportzeiten betreffen alle Ereignisse'' und ``Vektorzeiten betreffen alle Ereignisse'', die standardmäßig auf \textit{false} gesetzt sind. Mit \textit{true} werden alle Ereignisse, und nicht nur der Empfang oder das Versenden einer Nachricht, berücksichtigt. Für eine weitere Betrachtung der Lamport- sowie Vektor-Zeitstempel siehe \cite{Vorlesung} oder \cite{Tanenbaum}.
+Wie bereits beschrieben (s. Kap. 2.4.2.) gibt es in den Simulationseinstellungen die boolschen Variablen ``Lamportzeiten betreffen alle Ereignisse'' und ``Vektorzeiten betreffen alle Ereignisse'', die standardmäßig auf \textit{false} gesetzt sind. Mit \textit{true} werden alle Ereignisse, und nicht nur der Empfang oder das Versenden einer Nachricht, berücksichtigt. Für eine weitere Betrachtung der Lamport- sowie Vektor-Zeitstempel siehe \cite{Vorlesung} oder \cite{Tanenbaum}.
+\newpage
\subsection{Simulation langsamer Verbindungen \small{\textit{(slow-connection.dat)}}}
Mit dem Simulator lassen sich auch langsame Verbindungen zu einem bestimmten Prozess simulieren. Für die Demonstration wird das Beispiel aus Kapitel 3.5. wieder aufgegriffen, wo das Protokoll zur internen Synchronisation (durch P1) mit der Christians-Methode (durch P3) parallel simuliert wurden. P2 stellt den Server beider Protokolle zur Verfügung. In diesem Szenario soll P3 eine schlechte Netzwerkverbindung besitzen, so dass Nachrichten von- und an P3 stets eine längere Übertragungszeit benötigen.
diff --git a/LaTeX/chapters/simulator.tex b/LaTeX/chapters/simulator.tex index b344c5e..c3e9a84 100644 --- a/LaTeX/chapters/simulator.tex +++ b/LaTeX/chapters/simulator.tex @@ -77,9 +77,9 @@ Mittig rechts befindet sich die grafische Simulationsvisualisierung. Die X-Achse Die Prozessbalken dienen auch für Start- und Zielpunkte von Nachrichten. Wenn beispielsweise Prozess 1 eine Nachricht an Prozess 2 verschickt, so wird eine Linie vom einen Prozessbalken zum anderen gezeichnet. Nachrichten, die ein Prozess an sich selbst verschicken, werden nicht visualisiert. Sie werden aber im Logfenster (mehr dazu später) protokolliert.
-Eine andere Möglichkeit einen Prozesseditor aufzurufen ist ein Linksklick auf den zum Prozess gehörigen Prozessbalken. Dies muss also nicht immer über das Simulator-Menü geschehen. Ein Rechtsklick hingegen öffnet ein Popup-Fenster mit weiteren Auswahlmöglichkeiten (s. Abb. \ref{fig:RechtsklickProzessbalken}.). Ein Prozess kann über das Popup-Menü nur während einer laufenden Simulation zu einem Absturz oder einer Wiederbelebung bewegt werden.
+Eine andere Möglichkeit einen Prozesseditor aufzurufen ist ein Linksklick auf den zum Prozess gehörigen Prozessbalken. Ein Rechtsklick hingegen öffnet ein Popup-Fenster mit weiteren Auswahlmöglichkeiten (s. Abb. \ref{fig:RechtsklickProzessbalken}.). Ein Prozess kann über das Popup-Menü nur während einer laufenden Simulation zu einem Absturz oder einer Wiederbelebung bewegt werden.
-Generell kann die Anzahl der Prozesse nach Belieben variieren. Die Dauer der Simulation beträgt mindestens \textit{5} und höchstens \textit{120} Sekunden. Die Simulation endet erst, wenn sie die globale Zeit, die angegebene Simulationsendzeit (hier \textit{15} Sekunden) erreicht hat, und nicht, wenn eine lokale Prozesszeit diese Endzeit erreicht.
+Generell kann die Anzahl der Prozesse nach Belieben variieren. Die Dauer der Simulation beträgt mindestens \textit{5} und höchstens \textit{120} Sekunden. Die Simulation endet erst, wenn sie die globale Zeit die angegebene Simulationsendzeit (hier \textit{15} Sekunden) erreicht hat, und nicht, wenn eine lokale Prozesszeit diese Endzeit erreicht.
\subsubsection{Farbliche Differenzierung}
@@ -153,7 +153,7 @@ Das Logfenster (s. Abb. \ref{fig:NeuErstellteSimulation}., unten) protokolliert \label{fig:Logfenster}
\end{figure}
-Mit dem Deaktivieren des Logging-Schalters lässt sich das Loggen von Nachrichten temporär ausstellen. Mit deaktiviertem Loggen werden keine neuen Nachrichten mehr ins Logfenster geschrieben. Nach Reaktivieren des Schalters werden alle ausgelassenen Nachrichten nachträglich in das Fenster geschrieben. Ein deaktiviertes Loggen kann zu verbessertem Leistungsverhalten des Simulators führen. Dieser Umstand ist der sehr langsamen Java-Implementierung der JTextArea-Klasse zu verdanken, die schnelle Updates nur sehr träge durchführt.
+Mit dem Deaktivieren des Logging-Schalters lässt sich das Loggen von Nachrichten temporär ausstellen. Mit deaktiviertem Loggen werden keine neuen Nachrichten mehr ins Logfenster geschrieben. Nach Reaktivieren des Schalters werden alle ausgelassenen Nachrichten nachträglich in das Fenster geschrieben. Ein deaktiviertes Loggen kann zu verbessertem Leistungsverhalten des Simulators führen. Dieser Umstand ist der sehr langsamen Java-Implementierung der JTextArea-Klasse zu verdanken, die Updates nur sehr träge durchführt (s. \cite{Swing}).
Über den Schalter ``Expertenmodus'' wird der Expertenmodus aktiviert, bzw. deaktiviert.
@@ -185,13 +185,13 @@ Weitere Unterschiede machen sich unterhalb des Logfensters bemerkbar. Dort gibt \label{fig:SidebarExpertenmodus}
\end{figure}
-Der Anti-Aliasing-Schalter ermöglicht dem Anwender Anti-Aliasing zu aktivieren bzw. zu deaktivieren. Mit Anti-Aliasing werden alle Grafiken der Visualisierung gerundet dargestellt. Aus Performance-Gründen ist Anti-Aliasing standardmäßig nicht aktiv.
+Der Anti-Aliasing-Schalter ermöglicht dem Anwender Anti-Aliasing zu aktivieren bzw. zu deaktivieren. Mit Anti-Aliasing werden alle Grafiken der Visualisierung gerundet dargestellt (s. \cite{Games}). Aus Performance-Gründen ist Anti-Aliasing standardmäßig nicht aktiv.
\subsubsection{Der Logfilter}
Je komplexer eine Simulation wird, desto unübersichtlicher werden die Einträge im Logfenster. Hier fällt es zunehmend schwerer die Übersicht aller Ereignisse zu behalten. Um dem entgegenzuwirken gibt es im Expertenmodus einen Logfilter, welcher es ermöglicht nur die wesentlichen Daten aus den Logs zu filtern.
-Der Logfilter wird anhand des dazugehörigen Schalters ``Filter'' aktiviert und deaktiviert. In der dahinterliegenden Eingabezeile kann ein regulärer Ausdruck in Java-Syntax, beschrieben in \cite{Regexp}, angegeben werden. Beispielsweise werden mit ``\textit{PID: (1|2)}'' nur Logzeilen angezeigt, die entweder ``\textit{PID: 1}'' oder ``\textit{PID: 2}'' beinhalten. Alle anderen Zeilen, die z.B. nur ``\textit{PID: 3}'' beinhalten, werden dabei nicht angezeigt. Mit Logfilter werden nur die Logzeilen angezeigt, auf die der angegebene reguläre Ausdruck passt. Der Logfilter kann auch nachträglich aktiviert werden, da bereits protokollierte Ereignisse nach jeder Filteränderung erneut gefiltert werden.
+Der Logfilter wird anhand des dazugehörigen Schalters ``Filter'' aktiviert und deaktiviert. In der dahinterliegenden Eingabezeile kann ein regulärer Ausdruck in Java-Syntax, angegeben werden. Die Verwendung regul\"{a}rer Ausdr\"{u}cke mittels Java wird in \cite{Regexp} behandelt. Beispielsweise werden mit ``\textit{PID: (1|2)}'' nur Logzeilen angezeigt, die entweder ``\textit{PID: 1}'' oder ``\textit{PID: 2}'' beinhalten. Alle anderen Zeilen, die z.B. nur ``\textit{PID: 3}'' beinhalten, werden dabei nicht angezeigt. Mit Logfilter werden nur die Logzeilen angezeigt, auf die der angegebene reguläre Ausdruck passt. Der Logfilter kann auch nachträglich aktiviert werden, da bereits protokollierte Ereignisse nach jeder Filteränderung erneut gefiltert werden.
Der Logfilter kann auch während einer laufenden Simulation verwendet werden. Bei Filterdeaktivierung werden alle Nachrichten wieder dargestellt. Lognachrichten, die aufgrund des Filters noch nie angezeigt wurden, werden dann nachträglich angezeigt.
@@ -204,11 +204,11 @@ Der Logfilter kann auch während einer laufenden Simulation verwendet werden. Bei \section{Ereignisse}
-Es wird zwischen zwei Haupttypen von Ereignissen unterschieden: Programmierbare Ereignisse und nicht programmierbare Ereignisse. Programmierbare Ereignisse lassen sich im Ereigniseditor programmieren und editieren und deren Eintrittszeiten hängen von den lokalen Prozessuhren oder der globalen Uhr ab. Nicht programmierbare Ereignisse lassen sich hingegen nicht im Ereigniseditor programmieren und treten nicht wegen einer bestimmten Uhrzeit ein, sondern aufgrund anderer Gegebenheiten wie z.B. das Eintreffen einer Nachricht oder das Ausführen einer Aktion aufgrund eines Weckers, worauf später nochmal genauer eingegangen wird.
+Es wird zwischen zwei Haupttypen von Ereignissen unterschieden: Programmierbare Ereignisse und nicht programmierbare Ereignisse. Programmierbare Ereignisse lassen sich im Ereigniseditor programmieren und editieren und deren Eintrittszeiten hängen von den lokalen Prozessuhren oder der globalen Uhr ab. Nicht programmierbare Ereignisse lassen sich hingegen nicht im Ereigniseditor programmieren und treten nicht wegen einer bestimmten Uhrzeit ein, sondern aufgrund anderer Gegebenheiten wie z.B. das Eintreffen einer Nachricht oder das Ausführen einer Aktion aufgrund eines Weckers (mehr dazu sp\"{a}ter).
\subsubsection{Prozessabsturz- und Wiederbelebung (programmierbar)}
-Die beiden einfachsten Ereignisse sind ``Prozessabsturz'' sowie ``Prozesswiederbelebung''. Wenn ein Prozess abgestürzt ist, so wird sein Prozessbalken in rot dargestellt. Ein abgestürzter Prozess kann keine weiteren Ereignisse mehr verarbeiten und wenn bei ihm eine Nachricht eintrifft, dann kann sie nicht verarbeitet werden und geht deshalb verloren. Die einzige Ausnahme bietet ein Wiederbelebungsereignis. Ein abgestürzter Prozess kann nichts, außer wiederbelebt werden. Während eines Prozessabsturzes läuft die lokale Prozessuhr, abgesehen von den Lamport- und Vektor-Zeitstempel, normal weiter. Das heißt, es besteht die Möglichkeit, dass ein Prozess einige seiner Ereignisse gar nicht ausführt, da er zu den Ereigniseintrittszeiten abgestürzt ist. Wenn im echten Leben ein Computer abstürzt oder abgeschaltet wird, dann läuft seine Hardware-Uhr unabhängig vom Betriebssystem auch weiter.
+Die beiden einfachsten Ereignisse sind ``Prozessabsturz'' sowie ``Prozesswiederbelebung''. Wenn ein Prozess abgestürzt ist, so wird sein Prozessbalken in rot dargestellt. Ein abgestürzter Prozess kann keine weiteren Ereignisse mehr verarbeiten und wenn bei ihm eine Nachricht eintrifft, dann geht sie verloren. Die einzige Ausnahme bietet ein Wiederbelebungsereignis. Ein abgestürzter Prozess kann nichts, außer wiederbelebt werden. Während eines Prozessabsturzes läuft die lokale Prozessuhr, abgesehen von den Lamport- und Vektor-Zeitstempel, normal weiter. Das heißt, es besteht die Möglichkeit, dass ein Prozess einige seiner Ereignisse gar nicht ausführt, da er zu den Ereigniseintrittszeiten abgestürzt ist.
\subsubsection{Aktivierung und Deaktivierung von Protokollen sowie Starten von Anfragen (programmierbar)}
Es ist bereits bekannt, dass ein Prozess mehrere Protokolle client- und auch serverseitig unterstützen kann. Welches Protokoll von einem Prozess unterstützt wird, kann der Anwender anhand von Protokollaktivierungs- und Protokolldeaktivierungsereignissen konfigurieren. Somit besteht die Möglichkeit, dass ein gegebener Prozess ein bestimmtes Protokoll erst zu einem bestimmten Zeitpunkt unterstützt und ggf. ein anderes Protokoll ablöst. Jedes Protokoll kann entweder server- oder clientseitig aktiviert bzw. deaktiviert werden. Der Anwender hat somit die Auswahl zwischen fünf verschiedenen Protokollereignistypen:
@@ -229,11 +229,11 @@ Nachdem ein Prozess eine Nachricht empfängt wird zuerst überprüft, ob er das daz \subsubsection{Callback-Ereignisse (nicht-programmierbar)}
-Ein Callback-Ereignis kann von einem Protokoll ausgelöst werden. Das Protokoll setzt einen Wecker, der angibt zur welcher lokalen Uhrzeit eine weitere Aktion ausgeführt werden soll. Zum Beispiel lassen sich hiermit Timeouts realisieren: Wenn ein Protokoll eine Antwort erwartet, diese aber nicht eintrifft, dann kann nach einer bestimmten Zeit eine Anfrage erneut verschickt werden! Es können beliebig viele Callback-Ereignisse definiert werden. Wenn sie noch nicht ausgeführt wurden und aufgrund eines anderen Ereignisses nicht mehr benötigt werden, dann können sie vom Protokoll wieder nachträglich entfernt werden. Wenn ein Callback-Ereignis ausgeführt wird, dann kann es sich selbst wieder für eine weitere Ausführung erneut planen. So lassen sich periodisch wieder-eintreffende Ereignisse realisieren. Beispielsweise verwenden die ``Commit-Protokolle'' (mehr dazu später) Callback-Ereignisse, indem solange Anfragen verschickt werden, bis alle benötigten Antworten vorliegen.
+Ein Callback-Ereignis kann von einem Protokoll ausgelöst werden. Das Protokoll setzt einen Wecker, der angibt zur welcher lokalen Uhrzeit eine weitere Aktion ausgeführt werden soll. Zum Beispiel lassen sich hiermit Timeouts realisieren: Wenn ein Protokoll eine Antwort erwartet, diese aber nicht eintrifft, dann kann nach einer bestimmten Zeit eine Anfrage erneut verschickt werden! Es können beliebig viele Callback-Ereignisse definiert werden. Wenn sie noch nicht ausgeführt wurden und aufgrund eines anderen Ereignisses nicht mehr benötigt werden, dann können sie vom Protokoll wieder nachträglich entfernt werden. Wenn ein Callback-Ereignis ausgeführt wird, dann kann es sich selbst wieder für eine weitere Ausführung erneut planen. So lassen sich periodisch wieder-eintreffende Ereignisse realisieren. Beispielsweise verwenden die sog. Commit-Protokolle (s. Kap. 3.3.7, 3.3.8) Callback-Ereignisse, indem solange Anfragen verschickt werden, bis alle benötigten Antworten vorliegen.
\subsubsection{Zufallsereignisse (nicht-programmierbar)}
-Die Eintrittszeit eines Zufallsereignisses wird vom Simulator zufällig gewählt. Es besteht lediglich die Möglichkeit die Wahrscheinlichkeit, dass das Ereignis überhaupt eintritt, einzustellen. Ein Beispiel ist ein zufälliger Prozessabsturz, dessen Wahrscheinlichkeit unter den Prozessvariablen konfiguriert werden kann. Diese Variable wird im Abschnitt über den Prozesseditor noch ausführlicher beschrieben.
+Die Eintrittszeit eines Zufallsereignisses wird vom Simulator zufällig gewählt. Es besteht lediglich die Möglichkeit die Wahrscheinlichkeit, dass das Ereignis überhaupt eintritt, einzustellen. Ein Beispiel ist ein zufälliger Prozessabsturz, dessen Wahrscheinlichkeit unter den Prozessvariablen konfiguriert werden kann (s. Kapitel 2.4.3.).
\section{Einstellungen}
@@ -270,7 +270,7 @@ In diesem Abschnitt wird genauer auf die möglichen Konfigurationsmöglichkeiten e \end{figure}
-Der Simulator unterscheidet zwischen mehreren Datentypen, in denen die einstellbaren Variablen vorliegen können (s. Tabelle \ref{tb:VariablenDatentypen}.). Jede Variable besitzt einen Namen, einen Wert und eine optionale Beschreibung. Wenn eine Variablenbeschreibung vorhanden ist, so wird sie anstelle des Variablennamen in einem Editor (mehr zu Editoren später) angezeigt. Der Variablenname wird vom Simulator lediglich für die interne Verwendung benötigt. Im folgenden bedeutet \textit{Typ: varname = wert}, dass die Variable vom Typ \textit{Typ} ist, der interne Variablenname \textit{varname} lautet, und standardmäßig den Wert \textit{wert} zugewiesen hat. Vom Anwender lassen sich lediglich die Variablenwerte, jedoch nicht die Variablentypen, Variablennamen und Beschreibungen ändern.
+Der Simulator unterscheidet zwischen mehreren Datentypen, in denen die einstellbaren Variablen vorliegen können (s. Tabelle \ref{tb:VariablenDatentypen}.). Jede Variable besitzt einen Namen, einen Wert und eine optionale Beschreibung. Wenn eine Variablenbeschreibung vorhanden ist, so wird sie anstelle des Variablennamen in einem Editor angezeigt. Der Variablenname wird vom Simulator lediglich für die interne Verwendung benötigt. Im folgenden bedeutet \textit{Typ: varname = wert}, dass die Variable vom Typ \textit{Typ} ist, der interne Variablenname \textit{varname} lautet, und standardmäßig den Wert \textit{wert} zugewiesen hat. Vom Anwender lassen sich lediglich die Variablenwerte, jedoch nicht die Variablentypen, Variablennamen und Beschreibungen ändern.
\subsection{Simulationseinstellungen}
@@ -291,7 +291,7 @@ Im Folgenden werden alle in den Simulationseinstellungen verfügbaren Variablen b \item \textbf{Prozesse empfangen eigene Nachrichten} \textit{(Boolean: sim.message.own.recv = false)}: Standardmäßig können Prozesse keine Nachrichten empfangen, die sie selbst verschickt haben. Dies trägt zur Übersichtlichkeit der Simulation bei. Wenn diese Variable jedoch auf \textit{true} gesetzt wird, dann kann ein Prozess auch selbst verschickte Nachrichten empfangen und auf diese ebenso antworten. Die Zeit für das Versenden und Empfangen einer Nachricht an sich selbst beträgt jedoch stets \textit{0ms}. Diese Variable sollte mit Vorsicht verwendet werden, da bedingt durch den \textit{0ms} Endlosschleifen entstehen können.
\item \textbf{Mittelwerte der Nachrichtenverlustwahrscheinlichkeiten bilden} \textit{(Boolean: sim.message.prob.mean = true)}: Jede Nachricht, die verschickt wird, hat, je nach Einstellungen, eine vom verschickenden Prozess abhängige zufällige Verlustwahrscheinlichkeit. Wenn diese Option aktiviert ist, wird der Mittelwert aus den Verlustwahrscheinlichkeiten des Senders- und Empfängerprozesses gebildet. Ansonsten wird die Verlustwahrscheinlichkeit, die beim Senderprozesses eingestellt wurde, verwendet.
\item \textbf{Mittelwerte der Übertragungszeiten bilden} \textit{(Boolean: sim.message.sendingtime.mean = true)}: Jede Nachricht, die verschickt wird, hat, je nach Einstellungen, eine vom verschickenden Prozess abhängige zufällige Übertragungszeit bis sie ihr Ziel erreicht (siehe Prozesseinstellungen später). Wenn diese Option aktiviert ist, wird der Mittelwert vom Sender- und Empfängerprozess gebildet. Ansonsten wird die Übertragungszeit, die beim Senderprozesses angegeben wurde, verwendet.
- \item \textbf{Nur relevante Nachrichten anzeigen} \textit{(Boolean: sim.messages.relevant = true)}: Wenn nur alle relevanten Nachrichten angezeigt werden, dann werden Nachrichten an einen Prozess die er selbst nicht verarbeiten kann nicht angezeigt, da er das dazugehörige Protokoll nicht unterstützt. Dadurch wird die \"{U}bersichtlichkeit verbessert Übersicht.
+ \item \textbf{Nur relevante Nachrichten anzeigen} \textit{(Boolean: sim.messages.relevant = true)}: Wenn nur alle relevanten Nachrichten angezeigt werden, dann werden Nachrichten an einen Prozess die er selbst nicht verarbeiten kann nicht angezeigt, da er das dazugehörige Protokoll nicht unterstützt. Dadurch wird die \"{U}bersichtlichkeit verbessert.
\item \textbf{Expertenmodus aktivieren} \textit{(Boolean: sim.mode.expert = false)}: Hier lässt sich der Expertenmodus aktivieren und deaktivieren. Alternativ kann dies über den gleichnamigen Schalter unterhalb des Logfensters geschehen.
\item \textbf{Simulation periodisch wiederholen} \textit{(Boolean: sim.periodic = false)}: Wenn diese Variable auf \textit{true} gesetzt ist, dann wird die Simulation jedes Mal nach Ablauf automatisch neu gestartet.
\item \textbf{Lamportzeiten betreffen alle Ereignisse} \textit{(Boolean: sim.update.lamporttime.all = false)}: Wenn diese Variable auf \textit{true} gesetzt ist, dann werden bei jedem Ereignis alle Lamport-Zeitstempel aller Prozesse inkrementiert. Bei einem Wert \textit{false} werden die Lamport-Zeitstempel jeweils nur inkrementiert, wenn eine Nachricht empfangen oder verschickt wurde.
@@ -301,7 +301,7 @@ Im Folgenden werden alle in den Simulationseinstellungen verfügbaren Variablen b \item \textbf{Dauer der Simulation} \textit{(Integer: sim.seconds = 15)}: Gibt die Dauer der Simulation in Sekunden vor.
\end{itemize}
-Alle weiteren Simulationeinstellungen unter ``Einstellungen für neue Prozesse'' sowie ``Nachrichteneinstellungen für neue Prozesse'' definieren das Verhalten des jedes neu erzeugten Prozesses.
+Alle weiteren Simulationeinstellungen unter ``Einstellungen für neue Prozesse'' sowie ``Nachrichteneinstellungen für neue Prozesse'' definieren das Verhalten des jeden neu erzeugten Prozesses.
\begin{table}
\centering
@@ -335,7 +335,11 @@ Alle weiteren Simulationeinstellungen unter ``Einstellungen für neue Prozesse'' Jeder Prozess besitzt folgende Variablen:
\begin{itemize}
- \item \textbf{Uhrabweichung} \textit{(Float: process.clock.variance = 0.0)}: Gibt den Wert an, um den die lokale Prozessuhr abweicht. Der Wert \textit{0.0} besagt beispielsweise, dass die Uhr keine Abweichung hat und somit global-korrekt läuft. Ein Wert von \textit{1.0} hingegen bedeuten, dass die Uhr mit doppelter Geschwindigkeit l\"{a}uft. Ein Wert von \textit{-0.5} bedeutet, dass die lokale Prozessuhr mit halber globaler Geschwindigkeit fortschreitet. Es sind nur Werte > \textit{-1.0} erlaubt, da sonst die Prozessuhr rückwärts laufen könnte. Bei allen anderen Werten wird die Einstellung wieder automatisch auf \textit{0.0} gesetzt. Der Simulator arbeitet intern mit Fließkommazahlen doppelter Genauigkeit arbeitet, so dass es es zu kleinen, jedoch vernachlässigbaren Rundungsfehlern kommen.
+ \item \textbf{Uhrabweichung} \textit{(Float: process.clock.variance = 0.0)}: Gibt den Wert $t_v$ an, um den die lokale Prozessuhr $t$ abweicht. Wenn $t_n$ die neu verstrichene Zeit ist, dann wird die lokale Prozessuhr wie folgt neu berechnet:
+\begin{equation*}
+ t := t + t_n * t_v
+\end{equation*}
+ Der Wert \textit{0.0} besagt beispielsweise, dass die Uhr keine Abweichung hat und somit global-korrekt läuft. Ein Wert von \textit{1.0} hingegen bedeuten, dass die Uhr mit doppelter Geschwindigkeit l\"{a}uft. Ein Wert von \textit{-0.5} bedeutet, dass die lokale Prozessuhr mit halber globaler Geschwindigkeit fortschreitet. Es sind nur Werte > \textit{-1.0} erlaubt, da sonst die Prozessuhr rückwärts laufen könnte. Bei allen anderen Werten wird die Einstellung wieder automatisch auf \textit{0.0} gesetzt. Der Simulator arbeitet intern mit Fließkommazahlen doppelter Genauigkeit arbeitet, so dass es es zu kleinen, jedoch vernachlässigbaren Rundungsfehlern kommen.
\item \textbf{Prozessausfallwahrscheinlichkeit} \textit{(Integer: process.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, mit der der Prozess während der Simulation zufällig abstürzt. Die Wahrscheinlichkeit bezieht sich auf die komplette Simulationsdauer. Bei einer Einstellung von \textit{100} Prozent und der Simulationsdauer von \textit{15} Sekunden stürzt der Prozess auf jeden Fall zwischen \textit{0ms} und \textit{15000ms} ab. An welcher Stelle dies geschieht wird zufällig bestimmt. Wenn der Prozess nach seinem Absturz wiederbelebt wird, stürzt er nicht mehr ab. Dies gilt allerdings nicht, wenn die Prozesseinstellungen nach dem Zufallsabsturz erneut geändert und übernommen werden, da dann das Zufallsabstürzereignis erneut erstellt wird.
\item \textbf{Lokale Zeit} \textit{(Long: process.localtime = 0)}: Gibt die lokale Prozesszeit in Millisekunden an.
\item \textbf{Nachrichtenverlustwahrscheinlichkeit} \textit{(Integer: message.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, mit der eine vom aktuell ausgewählten Prozess verschickte Nachricht unterwegs verloren geht. An welcher Stelle die Nachricht zwischen dem Sende- und Empfängerprozess verloren geht wird zufällig bestimmt.
@@ -354,7 +358,7 @@ Das heißt, dass die Nachricht nach einer zufälligen Zeit zwischen $t_{min}$ und t_e := t_g + \frac{1}{2} (rand(t_{min}, t_{max}) + rand(t'_{min}, t'_{max}))
\end{equation*}
-Das bedeutet, dass stets der Mittelwert der Nachrichtenübertragungszeiten vom Sender- und Empfängerprozesses verwendet wird.
+Das bedeutet, dass der Mittelwert der Nachrichtenübertragungszeiten vom Sender- und Empfängerprozesses verwendet wird.
\end{itemize}
|
