summaryrefslogtreecommitdiff
path: root/LaTeX/chapters
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2008-08-10 22:53:18 +0000
committerPaul Buetow <paul@buetow.org>2008-08-10 22:53:18 +0000
commitd49b270484f0d1d069e4ad2300a6d99dbe10e0ba (patch)
tree855b467e0224508cf0e3ebb9673be2e5b7b8fce9 /LaTeX/chapters
parent4c9cf79770dddfe2b2e7d25ffa61b0116568eadf (diff)
fixes
Diffstat (limited to 'LaTeX/chapters')
-rw-r--r--LaTeX/chapters/implementierung.tex10
-rw-r--r--LaTeX/chapters/introduction.tex12
-rw-r--r--LaTeX/chapters/simulator.tex47
3 files changed, 35 insertions, 34 deletions
diff --git a/LaTeX/chapters/implementierung.tex b/LaTeX/chapters/implementierung.tex
index 8d281ce..ed70dc3 100644
--- a/LaTeX/chapters/implementierung.tex
+++ b/LaTeX/chapters/implementierung.tex
@@ -137,7 +137,7 @@ In der Implementierung wird zwischen drei Haupttypen von Ereignissen unterschied
\item \textit{events.internal}: In diesem Paket befinden sich alle Ereignisse, die vom Simulator intern verwendet werden. Bevor der Simulator von diesen Ereignissen Gebrauch machen kann, muss er vorher einige Spezialbehandlungen durchführen.
\begin{itemize}
\item \textit{VSAbstractInternalEvent}: Diese Klasse stellt weitere Methoden zur Verfügung, die von allen internen Ereignissen benötigt werden. Derzeit betrifft dies nur Methoden zur Serialisierung der gegebenen Objekte. Auf die Serialisierung (Abspeichern/Laden) von Simulationen wird später noch genauer eingegangen.
- \item \textit{VSMessageReceiveEvent}: Diese Klasse wird für die Ankunft einer Nachricht bei einem Empfangsprozess benötigt. Sie kapselt die eigentliche Nachricht und überprüft, ob der Empfangsprozess das zur Nachricht dazugehörige Protokoll versteht. Diese Klasse überprüft auch die Simulationseinstellung ``Nur relevante Nachrichten anzeigen'' und entscheidet, ob die Nachricht nach Eintreffen in der Visualisierung und im Loggfenster berücksichtigt werden soll oder nicht.
+ \item \textit{VSMessageReceiveEvent}: Diese Klasse wird für die Ankunft einer Nachricht bei einem Empfängerprozess benötigt. Sie kapselt die eigentliche Nachricht und überprüft, ob der Empfängerprozess das zur Nachricht dazugehörige Protokoll versteht. Diese Klasse überprüft auch die Simulationseinstellung ``Nur relevante Nachrichten anzeigen'' und entscheidet, ob die Nachricht nach Eintreffen in der Visualisierung und im Loggfenster berücksichtigt werden soll oder nicht.
\item \textit{VSProtocolEvent}: Diese Klasse implementiert gleichzeitig vier verschiedene Ereignisse: Das Aktivieren/Deaktivieren eines Servers/Clients eines gegebenen Protokolls. Der Ereigniseditor berechnet anhand der verfügbaren Protokolle automatisch alle möglichen Kombinationen und bietet sie dem Anwender in seiner Auswahl an. Für alle dieser vier Ereignisse wird jeweils ein Objekt von \textit{VSProtocolEvent} verwendet, jedoch mit jeweils anderen Attributwerten.
\item \textit{VSProtocolScheduleEvent}: Diese Klasse wird für die Wecker-Ereignisse benötigt. Wecker-Ereignisse können nur von Protokollen (mehr dazu später) erstellt werden. \textit{VSProtocolScheduleEvent} besitzt eine Referenz auf das gegebene Protokoll und ruft bei Ereigniseintrittszeit entweder die Methode \textit{onServerScheduleStart} bei einem Server- oder \textit{onClientScheduleStart} bei einem Clientprotokoll auf.
\end{itemize}
@@ -241,7 +241,7 @@ Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-O
Jede Simulation besitzt genau eine Instanz von \textit{VSTaskManager}. Eine Instanz dieser Klasse stellt den Task-Manager dar. Er verwaltet alle \textit{VSTask}-Instanzen und überprüft periodisch, ob es auszuführende Ereignisse gibt. Der Task-Manager unterscheidet zwischen globalen und lokalen Ereignissen. Hierbei werden alle globalen Ereignisse (gekapselt in einem \textit{VSTask}-Objekt) in einer Prioritäts-Warteschlange abgelegt. Die Prioritäts-Warteschlange stellt hierbei die korrekte Ereigniseintrittsreihenfolge sicher. Da sich die lokalen Zeiten aller beteiligten Prozesse voneinander unterscheiden können, muss für jeden Prozess eine separate lokale Prioritäts-Warteschlange verwendet werden, auf die jedes Prozessobjekt seine eigene Referenz hat. In den lokalen Warteschlangen sind die geplanten lokalen Ereignisse (auch gekapselt in einem \textit{VSTask}-Objekt) abgelegt. Der Task-Manager greift über eine \textit{java.util.ArrayList} auf alle Prozessobjekte zu und kann somit auch auf alle lokalen Warteschlangen zugreifen und verwalten.
-Eine Instanz von \textit{VSMessage} stellt eine Nachricht dar, die von einem Prozess verschickt wird. Für jedes Versenden einer Nachricht wird hiervon eine Instanz gebildet, wo der Senderprozess die zu verschickende Daten ablegt. Da \textit{VSMessage} von \textit{VSPrefs} erbt, können zwischen zwei Prozessen beliebige Datentypen (Tabelle \ref{tb:VariablenDatentypen}) über eine Nachricht verschickt werden. Anschließend wird für jeden Empfangsprozess das neues Ereignisobjekt der Klasse \textit{VSMessageReceiveEvent} angelegt, welches eine Referenz der verschickten Nachricht besitzt (Abbildung \ref{fig:Wrapping}). Danach wird ein \textit{VSTask}-Objekt instantiiert, wo die Referenz auf das Ereignisobjekt und das dazugehörige Prozessobjekt sowie die Ereigniseintrittszeit als Attribute gespeichert werden. Das \textit{VSTask}-Objekt wird dann dem Task-Manager übergeben, der das dazugehörige Ereignis ausführt, wenn die Ereigniseintrittszeit eingetroffen ist. Via Java-Polymorphie wird das \textit{VSMessageReceiveEvent}-Objekt in ein \textit{VSAbstractEvent} umgewandelt.
+Eine Instanz von \textit{VSMessage} stellt eine Nachricht dar, die von einem Prozess verschickt wird. Für jedes Versenden einer Nachricht wird hiervon eine Instanz gebildet, wo der Senderprozess die zu verschickende Daten ablegt. Da \textit{VSMessage} von \textit{VSPrefs} erbt, können zwischen zwei Prozessen beliebige Datentypen (Tabelle \ref{tb:VariablenDatentypen}) über eine Nachricht verschickt werden. Anschließend wird für jeden Empfängerprozess das neues Ereignisobjekt der Klasse \textit{VSMessageReceiveEvent} angelegt, welches eine Referenz der verschickten Nachricht besitzt (Abbildung \ref{fig:Wrapping}). Danach wird ein \textit{VSTask}-Objekt instantiiert, wo die Referenz auf das Ereignisobjekt und das dazugehörige Prozessobjekt sowie die Ereigniseintrittszeit als Attribute gespeichert werden. Das \textit{VSTask}-Objekt wird dann dem Task-Manager übergeben, der das dazugehörige Ereignis ausführt, wenn die Ereigniseintrittszeit eingetroffen ist. Via Java-Polymorphie wird das \textit{VSMessageReceiveEvent}-Objekt in ein \textit{VSAbstractEvent} umgewandelt.
Erwähnenswert ist auch die Klasse \textit{VSMessageStub}, welche ein \textit{VSMessage} kapselt. Ihr Zweck ist das Verstecken einiger Methoden vor dem Protokoll-API, welches für die Erstellung eigener Protokolle dient. Der Protokoll-Entwickler soll möglichst nichts falsch machen können und deswegen soll den Protokoll-API ein eingeschränkter Funktionsumfang zur Verfügung gestellt werden. Da sich \textit{VSMessageStub} im selben Paket wie \textit{VSMessage} befindet, kann \textit{VSMessageStub} auf paket-private Methoden von \textit{VSMessage} zugreifen. Protokolle hingegen werden in einem anderen Paket implementiert und haben somit keinen Zugriff auf diese paket-privaten Methoden. Zwar kann der Protokollentwickler ein eigenes \textit{VSMessageStub}-Objekt anlegen, jedoch kann er auf diese Weise besser unterscheiden auf welche Methoden er zugreifen sollte und auf welche nicht. Das Protokoll-API wird später genauer behandelt.
@@ -252,7 +252,7 @@ Erwähnenswert ist auch die Klasse \textit{VSMessageStub}, welche ein \textit{VSM
\label{fig:Wrapping}
\end{figure}
-Der Task-Manager speichert anschließend in der globalen Warteschlange die Nachrichtenempfangsereignisse. Die Nachricht kommt bei einem Empfangsprozess an, sobald das Ereignis für den Empfang eintritt. Für die korrekte Implementierung der Lamport- und Vektor-Zeitstempel wird jeder Nachricht automatisch eine Referenz auf die Lamport- sowie auf die Vektorzeit des sendenden Prozesses als Attribut beigefügt. Für die Überprüfung des Protokolls wird in jeder Nachricht auch der Klassenname des jeweiligen Protokolls abgespeichert.
+Der Task-Manager speichert anschließend in der globalen Warteschlange die Nachrichtenempfangsereignisse. Die Nachricht kommt bei einem Empfängerprozess an, sobald das Ereignis für den Empfang eintritt. Für die korrekte Implementierung der Lamport- und Vektor-Zeitstempel wird jeder Nachricht automatisch eine Referenz auf die Lamport- sowie auf die Vektorzeit des sendenden Prozesses als Attribut beigefügt. Für die Überprüfung des Protokolls wird in jeder Nachricht auch der Klassenname des jeweiligen Protokolls abgespeichert.
Eine Instanz von \textit{VSInternalProcess} repräsentiert einen simulierten Prozess. Ein \textit{VSInternalProcess} stellt alle vom Simulator intern verwendeten Methoden zur Verfügung, während ein \textit{VSAbstractProcess} lediglich Methoden hat, die der Protokollentwickler für die Erstellung eigener Protokolle verwenden darf. Da \textit{VSAbstractProcess} abstrakt ist und hiervon keine Instanz gebildet werden darf, muss für einen neuen Prozesses stets ein \textit{VSInternalProcess}-Objekt erstellt werden. Via Polymorphie wird dieses Objekt nach \textit{VSAbstractProcess} umgewandelt und so dem Protokoll-API zur Verfügung gestellt. Beispielsweise darf mit \textit{getTasks()} nur vom Simulator intern auf die Prioritäts-Warteschlangen zugegriffen werden, während man im Protokoll-API selbiges vermeiden sollte und auch gar nicht direkt möglich ist. Hierfür hätte man auch ein Stub-Objekt \textit{VSProcessStub} implementieren können. Da aber so gut wie alle paar Millisekunden auf die Methoden von \textit{VSInternalProcess} zugegriffen wird, wurde hier aus Performancegründen der Weg über eine Vererbungungsstufe preferiert.
@@ -426,7 +426,7 @@ Wenn die Simulation zurückgesetzt wird, dann wird auch \textit{pids} reinitialis
}
\end{code}
-In \textit{onClientStart} wird geprüft, ob eine Clientanfrage gestartet werden soll. Wenn dies der Fall ist (wenn von mindestens einem beteiligten Prozess noch keine Bestätigung erhalten wurde), wird ein neues Nachrichtenobjekt erstellt, und mit dem Inhalt \textit{Boolean: isMulticast=true} verschickt (intern wird hier für jeden Empfangsprozess ein \textit{VSMessageReceiveEvent} erzeugt). Mit \textit{scheduleAt} wird ein Wecker festgelegt, zur welchen lokalen Prozesszeit die Methode \textit{onClientSchedule} aufgerufen werden soll (intern wird hier ein \textit{VSProtocolScheduleEvent} erzeugt):
+In \textit{onClientStart} wird geprüft, ob eine Clientanfrage gestartet werden soll. Wenn dies der Fall ist (wenn von mindestens einem beteiligten Prozess noch keine Bestätigung erhalten wurde), wird ein neues Nachrichtenobjekt erstellt, und mit dem Inhalt \textit{Boolean: isMulticast=true} verschickt (intern wird hier für jeden Empfängerprozess ein \textit{VSMessageReceiveEvent} erzeugt). Mit \textit{scheduleAt} wird ein Wecker festgelegt, zur welchen lokalen Prozesszeit die Methode \textit{onClientSchedule} aufgerufen werden soll (intern wird hier ein \textit{VSProtocolScheduleEvent} erzeugt):
\begin{code}
public void onClientStart() {
if (pids.size() != 0) {
@@ -580,7 +580,7 @@ for (i = s; i < s + v + p && i < e; i++)
\item Bei Punkt 2 mit neuer Startzeit $s := s + v + p$ weitermachen.
\end{enumerate}
-Hinzu kommt noch die Berücksichtigung der Simulationsvariable \textit{sim.clock.speed}, die wegen der Übersicht im Algorithmus nicht dargestellt wurde. Intern hat der Simulator die echte Zeit und die Simulationszeit abgespeichert. Es werden ständig die verstrichenen echten Zeiten gemessen und anschließend anhand von \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Rundungsfehler werden pro Durchgang in eine \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert und wenn der Betrag der Rundungsfehler $>= 1$ ist, dann werden davon die ganzen Wertanteile in der Simulationszeit berücksichtigt.
+Hinzu kommt noch die Berücksichtigung der Simulationsvariable \textit{sim.clock.speed}, die wegen der Übersicht im Algorithmus nicht dargestellt wurde. Intern hat der Simulator die echte Zeit und die Simulationszeit abgespeichert. Es werden ständig die verstrichenen echten Zeiten gemessen und anschließend anhand von \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Rundungsfehler werden pro Durchgang in eine \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert und wenn der Betrag der Rundungsfehler $>= 1$ ist, dann werden davon die ganzen Wertanteile in der Simulationszeit berücksichtigt. F\"{u}r jede lokale Prozesszeit sowie der dazugeh\"{o}rigen lokalen Uhrabweichung und den lokale Ereignisse wird \"{a}hnlich verfahren.
Jede Simulation besitzt somit seinen eigenen Simulationsthread. Bei mehreren parallel laufenden Simulationen laufen auch mehrere parallele voneinander unabhängige Threads. Des Weiteren gibt es noch den Java Swing-Thread, der für die GUI und der Anwenderinteraktion zuständig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen. Anwendereingriffe werden deswegen synchronisiert, da es ansonsten zu zeitgleichen Zugriffen/Änderungen gleicher Objekte kommen kann und somit eine Java-Ausnahme geworfen wird die das Stoppen eines Threads verursacht.
diff --git a/LaTeX/chapters/introduction.tex b/LaTeX/chapters/introduction.tex
index 0ff4fd1..7cc65b3 100644
--- a/LaTeX/chapters/introduction.tex
+++ b/LaTeX/chapters/introduction.tex
@@ -25,7 +25,7 @@ Für das Grundverständnis werden im Folgenden einige Grundlagen erläutert. Eine V
\label{fig:ClientServer}
\end{figure}
-Der Simulator basiert auf dem Client/Server Prinzip. Jeder Simulation besteht in der Regel aus einen teilnehmenden Client und einen Server, die miteinander über Nachrichten kommunizieren (Abbildung \ref{fig:ClientServer}). Bei komplexen Simulationen können auch mehrere Clients und/oder Server mitwirken.
+Der Simulator basiert auf dem Client/Server-Prinzip. Jeder Simulation besteht in der Regel aus einen teilnehmenden Client und einen Server, die miteinander über Nachrichten kommunizieren (Abbildung \ref{fig:ClientServer}). Bei komplexen Simulationen können auch mehrere Clients und/oder Server mitwirken.
\subsubsection{Prozesse und deren Rollen}
@@ -39,6 +39,10 @@ In einem verteiltem System müssen Nachrichten verschickt werden können. Eine Nac
In einer Simulation gibt es \textbf{genau eine} globale Uhr. Sie stellt die aktuelle und \textbf{immer korrekte} Zeit dar. Eine globale Uhr geht nie falsch.
+Zudem besitzt jeder beteiligter Prozess eine eigene lokale Uhr. Sie stellt die aktuelle Zeit des jeweiligen Prozesses dar. Im Gegensatz zu der globalen Uhr können lokale Uhren eine falsche Zeit anzeigen. Wenn die Prozesszeit nicht global-korrekt ist (nicht der globalen Zeit gleicht beziehungsweise eine falsche Zeit anzeigt), dann wurde sie entweder im Laufe einer Simulation neu gestellt, oder sie geht wegen einer Uhrabweichung falsch. Die Uhrabweichung gibt an, um welchen Faktor die Uhr falsch geht. Hierauf wird später genauer eingegangen.
+
+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 Lamportzeitstempel 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 anhand einer Simulation behandelt.
+
\begin{figure}[htbp]
\centering
\includegraphics{images/client-server-protokolle}
@@ -46,13 +50,9 @@ In einer Simulation gibt es \textbf{genau eine} globale Uhr. Sie stellt die aktu
\label{fig:ClientServerProtokolle}
\end{figure}
-Zudem besitzt jeder beteiligter Prozess eine eigene lokale Uhr. Sie stellt die aktuelle Zeit des jeweiligen Prozesses dar. Im Gegensatz zu der globalen Uhr können lokale Uhren eine falsche Zeit anzeigen. Wenn die Prozesszeit nicht global-korrekt ist (nicht der globalen Zeit gleicht beziehungsweise eine falsche Zeit anzeigt), dann wurde sie entweder im Laufe einer Simulation neu gestellt, oder sie geht wegen einer Uhrabweichung falsch. Die Uhrabweichung gibt an, um welchen Faktor die Uhr falsch geht. Hierauf wird später genauer eingegangen.
-
-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 Lamportzeitstempel 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 anhand einer Simulation behandelt.
-
\subsubsection{Ereignisse}
-Eine Simulation besteht aus der Hintereinanderausführung von endlich vielen Ereignissen. Beispielsweise kann es ein Ereignis geben, welches einen Prozess eine Nachricht verschicken lässt. Denkbar wäre auch ein Prozessabsturzereignis. Jedes Ereignis tritt zu einem bestimmten Zeitpunkt ein. Ereignisse mit selber Eintrittszeit werden vom Simulator direkt hintereinander ausgeführt. Den Anwendern des Simulators hindert dies jedoch nicht, da Ereignisse aus seiner Sicht parallel ausgeführt werden können.
+Eine Simulation besteht aus der Hintereinanderausführung von endlich vielen Ereignissen. Beispielsweise kann es ein Ereignis geben, welches einen Prozess eine Nachricht verschicken lässt. Denkbar wäre auch ein Prozessabsturzereignis. Jedes Ereignis tritt zu einem bestimmten Zeitpunkt ein. Ereignisse mit selber Eintrittszeit werden vom Simulator direkt hintereinander ausgeführt. Den Anwendern des Simulators hindert dies jedoch nicht, da Ereignisse aus ihrer Sicht parallel ausgeführt werden.
\subsubsection{Protokolle}
diff --git a/LaTeX/chapters/simulator.tex b/LaTeX/chapters/simulator.tex
index 6a3e162..7dd24f0 100644
--- a/LaTeX/chapters/simulator.tex
+++ b/LaTeX/chapters/simulator.tex
@@ -138,8 +138,7 @@ Für die Erstellung eines neuen Ereignisses kann der Anwender entweder mit einem
Mit einem Rechtsklick auf den Ereigniseditor lassen sich alle selektierten Ereignisse entweder kopieren oder löschen. Mithilfe der Strg-Taste können auch mehrere Ereignisse gleichzeitig markiert werden. Die Einträge der Spalten für die Zeit und der PID lassen sich nachträglich editieren. Somit besteht eine komfortable Möglichkeit bereits programmierte Ereignisse auf eine andere Zeit zu verschieben oder einen anderen Prozess zuzuweisen. Allerdings sollte der Anwender darauf achten, dass er nach dem ändern der Ereigniseintrittszeit die Enter-Taste betätigt, da sonst die Änderung unwirksam ist.
-In der Sidebar gibt es neben dem Ereignis-Tab einen weiteren Tab ``Variablen''. Hinter diesem Tab verbirgt sich der Prozesseditor des aktuell ausgewählten Prozesses (Abbildung \ref{fig:NeueSimulationVariablen} links). Dort können alle Variablen des Prozesses editiert werden und ist somit eine weitere Möglichkeit einen Prozesseditor aufzurufen. Der Prozesseditor wird später genauer behandelt.
-
+In der Sidebar gibt es neben dem Ereignis-Tab einen weiteren Tab ``Variablen''. Hinter diesem Tab verbirgt sich der Prozesseditor des aktuell ausgewählten Prozesses (Abbildung \ref{fig:NeueSimulationVariablen} links). Dort können alle Variablen des Prozesses editiert werden und ist somit eine weitere Möglichkeit einen Prozesseditor aufzurufen.
\subsubsection{Das Loggfenster}
@@ -150,7 +149,7 @@ In der Sidebar gibt es neben dem Ereignis-Tab einen weiteren Tab ``Variablen''.
\label{fig:Loggfenster}
\end{figure}
-Das Loggfenster (Abbildung \ref{fig:NeuErstellteSimulation}, unten) protokolliert in chronologischer Reihenfolge alle eingetroffenen Ereignisse. Auf Abbildung \ref{fig:Loggfenster} ist das Loggfenster nach Erstellung der Demo-Simulation zu sehen, an welcher 3 Prozesse beteiligt sind. Am Anfang eines Loggeintrages wird stets die globale Zeit in Millisekunden protokolliert. Bei jedem Prozess werden ebenso seine lokale Zeiten sowie die Lamport- und die Vektor-Zeitstempel aufgeführt. Letztere werden später genauer behandelt. Hinter den Zeitangaben werden weitere Angaben, wie beispielsweise welche Nachricht mit welchem Inhalt verschickt wurde und welchem Protokoll sie angehört, gemacht. Dies wird später noch anhand von Beispielen demonstriert.
+Das Loggfenster (Abbildung \ref{fig:NeuErstellteSimulation}, unten) protokolliert in chronologischer Reihenfolge alle eingetroffenen Ereignisse. Auf Abbildung \ref{fig:Loggfenster} ist das Loggfenster nach Erstellung der Demo-Simulation zu sehen, an welcher 3 Prozesse beteiligt sind. Am Anfang eines Loggeintrages wird stets die globale Zeit in Millisekunden protokolliert. Bei jedem Prozess werden ebenso seine lokale Zeiten sowie die Lamport- und die Vektor-Zeitstempel aufgeführt. Hinter den Zeitangaben werden weitere Angaben, wie beispielsweise welche Nachricht mit welchem Inhalt verschickt wurde und welchem Protokoll sie angehört, gemacht. Dies wird später noch anhand von Beispielen demonstriert.
Mit dem Deaktivieren des Logging-Schalters läßt sich das Loggen von Nachrichten temporär ausstellen. Mit deaktiviertem Loggen werden keine neuen Nachrichten mehr ins Loggfenster 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 (z.B. kein Rucklen; ist vom verwendeten Computer, auf dem der Simulator läuft, abhängig). Dieser Umstand ist der sehr langsamen Java-Implementierung der JTextArea-Klasse zu verdanken, die schnelle Updates nur sehr träge durchführt.
@@ -171,7 +170,7 @@ Der Simulator kann in zwei verschiedenen Modi betrieben werden. Es gibt einen ei
Der erste Unterschied ist in der Sidebar erkennbar (Abbildung \ref{fig:SidebarExpertenmodus}). Dort sind nun, zusätzlich den lokalen Ereignissen, auch globale Ereignisse editierbar. Wie bereits erwähnt sind unter lokale Ereignisse diejenigen Ereignisse zu verstehen, die auftreten, wenn eine bestimmte lokale Zeit des dazugehörigen Prozesses eingetreten ist. Globale Ereignisse hingegen sind diejenigen Ereignisse, die auftreten, wenn eine bestimmte globale Zeit eingetreten ist. Ein globales Ereignis nimmt die globale Zeit- und ein lokales Ereignis die lokale Prozesszeit als Eintrittskriterium. Globale Ereignisse machen somit nur einen Unterschied, wenn sich die lokalen Prozesszeiten von der globalen Zeit unterscheiden.
-Des Weiteren kann der Anwender bei der Programmierung eines neuen Ereignisses direkt die dazugehörige PID selektieren. Im einfachen Modus wurde hier immer standardmäßig die PID des aktuell (in der obersten Combo-Box) ausgewählten Prozesses verwendet (hier mit PID 1). In dieser Combo-Box sollte der Anwender gegebenenfalls ``Alle Prozesse'' selektieren, damit im Ereigniseditor stets die Ereignisse aller Prozesse aufgelistet werden.
+Des Weiteren kann der Anwender bei der Programmierung eines neuen Ereignisses direkt die dazugehörige PID selektieren. Im einfachen Modus wurde hier immer standardmäßig die PID des aktuell (in der obersten Combo-Box) ausgewählten Prozesses verwendet (hier mit PID 1).
\subsubsection{Lamportzeit-, Vektorzeit- und Anti-Aliasing Schalter}
@@ -220,11 +219,11 @@ Es ist bereits bekannt, dass ein Prozess mehrere Protokolle client- und auch ser
\item Starten einer Client/Server-Anfrage eines gegebenen Protokolls
\end{itemize}
-Ob sich das Ereignis für das Starten einer Anfrage auf einen Client oder einen Server bezieht hängt vom verwendeten Protokoll ab. Es gibt Protokolle, wo der Client die Anfragen starten muss, und es gibt Protokolle, wo der Server diese Aufgabe übernimmt. Beispielsweise startet bei dem ``Ping-Pong Protokoll'' der Client- und bei dem ``Commit-Protokollen'' der Server immer die Anfragen. Es gibt kein Protokoll, wo der Client und der Server jeweils Anfragen starten können.
+Ob sich das Ereignis für das Starten einer Anfrage auf einen Client oder einen Server bezieht, hängt vom verwendeten Protokoll ab. Es gibt Protokolle, wo der Client die Anfragen starten muss, und es gibt Protokolle, wo der Server diese Aufgabe übernimmt. Beispielsweise startet bei dem ``Ping-Pong Protokoll'' der Client- und bei dem ``Commit-Protokollen'' der Server immer die Anfragen. Es gibt kein Protokoll, wo der Client und der Server jeweils Anfragen starten können.
\subsubsection{Nachrichtenempfang sowie Antwortnachrichten (nicht-programmierbar)}
-Nachdem ein Prozess eine Nachricht empfängt wird zuerst überprüft, ob er das dazugehörige Protokoll unterstützt. Wenn der Prozess das Protokoll unterstützt wird geschaut, ob es sich um eine Client- oder eine Servernachricht handelt. Wenn es sich um eine Clientnachricht handelt, so muß der Empfangsprozess das Protokoll serverseitig unterstützen und virce versa. Wenn alles passt, dann führt der Empfangsprozess die vom Protokoll definierten Aktionen aus. In der Regel berechnet der Prozess einen bestimmten Wert und schickt ihn über eine Antwortnachricht zurück. Es können aber auch beliebig andere Aktionen ausgeführt werden. Welche dies sind hängt vom Protokoll ab.
+Nachdem ein Prozess eine Nachricht empfängt wird zuerst überprüft, ob er das dazugehörige Protokoll unterstützt. Wenn der Prozess das Protokoll unterstützt wird geschaut, ob es sich um eine Client- oder eine Servernachricht handelt. Wenn es sich um eine Clientnachricht handelt, so muß der Empfängerprozess das Protokoll serverseitig unterstützen und virce versa. Wenn alles passt, dann führt der Empfängerprozess die vom Protokoll definierten Aktionen aus. In der Regel berechnet der Prozess einen bestimmten Wert und schickt ihn über eine Antwortnachricht zurück. Es können aber auch beliebig andere Aktionen ausgeführt werden. Welche dies sind hängt vom Protokoll ab.
\subsubsection{Callback-Ereignisse (nicht-programmierbar)}
@@ -269,7 +268,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 (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 (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.
\subsection{Simulationseinstellungen}
@@ -288,8 +287,8 @@ Im Folgenden werden alle in den Simulationseinstellungen verfügbaren Variablen b
\begin{itemize}
\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, so wird die der Mittelwert aus den Verlustwahrscheinlichkeiten vom Sender- und Empfangsprozess gebildet. Ansonsten wird stets die Verlustwahrscheinlichkeit, die beim Senderprozesses angegeben 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, so wird der Mittelwert vom Sender- und Empfangsprozess gebildet. Ansonsten wird stets die Übertragungszeit, die beim Senderprozesses angegeben wurde, verwendet.
+ \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, so wird hier der Mittelwert aus den Verlustwahrscheinlichkeiten vom Sender- und Empfängerprozess gebildet. Ansonsten wird stets die Verlustwahrscheinlichkeit, die beim Senderprozesses angegeben 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, so wird der Mittelwert vom Sender- und Empfängerprozess gebildet. Ansonsten wird stets 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, weil er das dazugehörige Protokoll nicht unterstützt, nicht angezeigt. Dies verbessert die Übersicht.
\item \textbf{Expertenmodus aktivieren} \textit{(Boolean: sim.mode.expert = false)}: Hier lässt sich der Expertenmodus aktivieren beziehungsweise deaktivieren. Alternativ kann dies über den gleichnamigen Schalter unterhalb des Loggfensters 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 erneut gestartet.
@@ -312,27 +311,27 @@ Jeder Prozess besitzt folgende Variablen, die entweder via dem Variablen-Tab in
\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} würde hingegen bedeuten, dass die Uhr mit doppelter Geschwindigkeit- und ein Wert von \textit{-0.5}, dass die lokale Prozessuhr mit halber Geschwindigkeit der globalen Uhr 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. Da der Simulator intern mit Fließkommazahlen doppelter Genauigkeit arbeitet, kann es zu kleinen, jedoch vernachlässigbaren, Rundungsfehlern kommen.
\item \textbf{Prozessausfallwahrscheinlichkeit} \textit{(Integer: process.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, ob der gegebene 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 noch einmal zufällig 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, ob eine vom aktuell ausgewählten Prozess verschickte Nachricht unterwegs verloren geht. An welcher Stelle die Nachricht zwischen dem Sende- und Empfangsprozess verloren geht wird vom Simulator zufällig gewählt.
- \item \textbf{Maximale Übertragungszeit} \textit{(Long: message.sendingtime.max = 2000)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht maximal benötigt, bis sie einen Empfangsprozess erreicht. Im weiteren Verlauf wird dieser Wert mit $t_{max}$ bezeichnet.
- \item \textbf{Minimale Übertragungszeit} \textit{(Long: message.sendingtime.min = 500)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht minimal benötigt, bis sie einen Empfangsprozess erreicht. Im weiteren Verlauf wird dieser Wert mit $t_{min}$ bezeichnet.
+ \item \textbf{Nachrichtenverlustwahrscheinlichkeit} \textit{(Integer: message.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, ob 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 vom Simulator zufällig gewählt.
+ \item \textbf{Maximale Übertragungszeit} \textit{(Long: message.sendingtime.max = 2000)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht maximal benötigt, bis sie einen Empfängerprozess erreicht. Im weiteren Verlauf wird dieser Wert mit $t_{max}$ bezeichnet.
+ \item \textbf{Minimale Übertragungszeit} \textit{(Long: message.sendingtime.min = 500)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht minimal benötigt, bis sie einen Empfängerprozess erreicht. Im weiteren Verlauf wird dieser Wert mit $t_{min}$ bezeichnet.
-Wenn die Übertragungszeiten von Nachrichten immer exakt die selbe Zeit in Anspruch nehmen sollen, dann müssen alle Prozesseinstellungen mit $t_{min} = t_{max}$ konfiguriert werden. Wenn die aktuelle globale Zeit $t_g$ ist und die Simulationseinstellung ``Mittelwerte der Übertragungszeit'' nicht aktiv ist, dann wird die Ereigniseintrittszeit $t_e$ für den Empfang der Nachricht wie folgt berechnet:
+Wenn die Übertragungszeiten von Nachrichten immer exakt die selbe Zeit in Anspruch nehmen sollen, dann müssen alle Prozesseinstellungen mit $t_{min} = t_{max}$ konfiguriert werden. Wenn die aktuelle globale Zeit $t_g$ ist und die Simulationseinstellung ``Mittelwerte der Übertragungszeiten bilden'' nicht aktiv ist, dann wird die Ereigniseintrittszeit $t_e$ für den Empfang der Nachricht wie folgt berechnet:
\begin{equation*}
t_e := t_g + rand(t_{min}, t_{max})
\end{equation*}
-Das heißt, dass die Nachricht nach einer zufälligen Zeit zwischen $t_{min}$ und $t_{max}$ beim Empfänger eintrifft. Für jeden Empfänger wird hierbei ein neuer Zufalls-wert gewählt. Für den Fall, dass die Einstellung ``Mittelwerte der Übertragungszeiten wählen'' aktiviert ist, und wenn $t'_{min}$ und $t'_{max}$ die beim Empfangsprozess eingestellten Werte entsprechen, dann wird die Nachrichtenempfangszeit wie folgt berechnet:
+Das heißt, dass die Nachricht nach einer zufälligen Zeit zwischen $t_{min}$ und $t_{max}$ beim Empfänger eintrifft. Für jeden Empfänger wird hierbei ein neuer Zufalls-wert gewählt. Für den Fall, dass die Einstellung ``Mittelwerte der Übertragungszeiten bilden'' aktiviert ist, und wenn $t'_{min}$ und $t'_{max}$ die beim Empfängerprozess eingestellten Werte entsprechen, dann wird die Nachrichtenempfangszeit wie folgt berechnet:
\begin{equation*}
t_e := t_g + \frac{1}{2} (rand(t_{min}, t_{max}) + rand(t'_{min}, t'_{max}))
\end{equation*}
-Das heißt, dass stets der Mittelwert der Nachrichtenübertragungszeiten des Sender- und Empfangsprozesses verwendet wird.
+Das heißt, dass stets der Mittelwert der Nachrichtenübertragungszeiten des Sender- und Empfängerprozesses verwendet wird.
\end{itemize}
-Im selben Fenster lassen sich auch die Protokollvariablen editieren. Die Protokollvariablen werden jedoch später bei den Protokollen beschrieben.
+Im selben Fenster (im Prozesseditor) lassen sich auch die Protokollvariablen editieren. Die Protokollvariablen werden jedoch später bei den Protokollen beschrieben.
\subsection{Einstellungen im Expertenmodus}
@@ -620,7 +619,7 @@ Im Beispiel auf Abbildung \ref{fig:BerkeleyProto} gibt es die 2 Clientprozesse P
Dieses Protokoll verwendet folgende serverseitige Variable, die in den Prozesseinstellungen unter dem Punkt ``Berkeley Server'' konfiguriert werden kann. Clientseitig gibt es hier keine Variablen.
\begin{itemize}
- \item \textbf{PIDs beteiliger 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 gar nicht existiert oder nicht das Berkeley Protokoll clientseitig gar nicht unterstützt. In diesem Fall würde ewig auf eine fehlende Clientantwort gewartet werden.
+ \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 gar nicht existiert oder nicht das Berkeley Protokoll clientseitig gar nicht unterstützt. In diesem Fall würde ewig auf eine fehlende Clientantwort gewartet werden.
\end{itemize}
\newpage
@@ -661,7 +660,7 @@ Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesse
\begin{itemize}
\item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Festschreibewunsch erneut verschickt wird.
- \item \textbf{PIDs beteiliger Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse, die festschreiben sollen.
+ \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse, die festschreiben sollen.
\end{itemize}
\newpage
@@ -700,7 +699,7 @@ Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesse
\begin{itemize}
\item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Festschreibewunsch erneut verschickt wird.
- \item \textbf{PIDs beteiliger Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse die über eine Festschreibung abstimmen und anschließend gegebenenfalls festschreiben sollen.
+ \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse die über eine Festschreibung abstimmen und anschließend gegebenenfalls festschreiben sollen.
\end{itemize}
Und folgende Clientvariable kann unter den Prozesseinstellungen unter dem Punkt ``2-Phasen Commit Client'' konfiguriert werden:
@@ -1045,7 +1044,7 @@ Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesse
\begin{itemize}
\item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Muticast erneut verschickt wird.
- \item \textbf{PIDs beteiliger Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Serverprozesse, die die Multicast-Nachricht erhalten sollen.
+ \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Serverprozesse, die die Multicast-Nachricht erhalten sollen.
\end{itemize}
\newpage
@@ -1068,7 +1067,7 @@ Die Vektor- und Lamportzeitstempel lassen sich sehr gut am bereits behandeltem B
t_l(j) := 1 + max(t_l(j), t_l(i))
\end{equation*}
-Es wird also stets die größere Lamportzeit vom Sender- und Empfangsprozess verwendet und anschließend wird diese um \textit{1} inkrementiert. Nach Ablauf der Berkeley-Simulation hat P1 \textit{(16)}, P2 (\textit{14}) und P3 (\textit{15}) als Lamportzeitstempel abgespeichert.
+Es wird also stets die größere Lamportzeit vom Sender- und Empfängerprozess verwendet und anschließend wird diese um \textit{1} inkrementiert. Nach Ablauf der Berkeley-Simulation hat P1 \textit{(16)}, P2 (\textit{14}) und P3 (\textit{15}) als Lamportzeitstempel abgespeichert.
\begin{figure}[h]
\centering
@@ -1077,7 +1076,7 @@ Es wird also stets die größere Lamportzeit vom Sender- und Empfangsprozess verwe
\label{fig:Vektorzeit}
\end{figure}
-Mit aktiven Vektorzeit-Schalter werden alle Vektor-Zeitstempel angezeigt (Abbildung \ref{fig:Vektorzeit}). Wie bei den Lamportzeitstempel 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$. über $v(i)$ kann jeder Prozess auf seinen lokalen Eintrag zugreifen. Wenn $v$ der Vektor-Zeitstempel des Empfangsprozesses $j$ ist und $w$ der Vektor-Zeitstempel des Senderprozesses ist, dann wird der neue lokale Vektorzeitstempel wie folgt (hier in Pseudo-Code angegeben) neu berechnet:
+Mit aktivem Vektorzeit-Schalter werden alle Vektor-Zeitstempel angezeigt (Abbildung \ref{fig:Vektorzeit}). Wie bei den Lamportzeitstempel 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$. über $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 Vektorzeitstempel wie folgt (hier in Pseudo-Code angegeben) neu berechnet:
\begin{code}
for (i := 0; i < n; i++) {
@@ -1089,7 +1088,7 @@ for (i := 0; i < n; i++) {
}
\end{code}
-Standardmäßig wird der Vektor-Zeitstempel nur inkrementiert, wenn eine Nachricht verschickt- oder erhalten wird. Bei beiden Fällen inkrementiert der Sender- und Empfangsprozess jeweils seinen eigenen Index im Vektor-Zeitstempel mit $v(i) = v(i) + 1$. Beim Empfang einer Nachricht wird anschließend der lokale Vektor-Zeitstempel mit dem des Senderprozesses verglichen und für alle Indizes stets der größere Wert in den lokalen Vektor-Zeitstempel übernommen.
+Standardmäßig wird der Vektor-Zeitstempel nur inkrementiert, wenn eine Nachricht verschickt- oder erhalten wird. Bei beiden Fällen inkrementiert der Sender- und Empfängerprozess jeweils seinen eigenen Index im Vektor-Zeitstempel mit $v(i) = v(i) + 1$. Beim Empfang einer Nachricht wird anschließend der lokale Vektor-Zeitstempel mit dem des Senderprozesses verglichen und für alle Indizes stets der größere Wert in den lokalen Vektor-Zeitstempel übernommen.
Im Beispiel auf Abbildung \ref{fig:Vektorzeit} hat P1 \textit{(8,10,6)}, P2 \textit{(6,10,6)} und P3 \textit{(6,10,8)} als Vektor-Zeitstempel abgespeichert.
@@ -1116,3 +1115,5 @@ Als Folge (Abbildung \ref{fig:TimeSync2LongTransferProto}) benötigen Nachrichten
\begin{equation*}
\frac{1}{2} (rand(500, 2000) + rand(2000, 8000)) = \frac{1}{2} rand(2500, 10000) = rand(1250, 5000) ms
\end{equation*}
+
+In dem Beispiel auf Abbildung \ref{fig:TimeSync2LongTransferProto} ist die lokale Prozesszeit von P1 bis auf \textit{20000 - 21446 = - 1446ms} synchronisiert, w\"{a}hrend die Prozesszeit von P3 satte \textit{20000 - 16557 = 3443ms} falsch geht.