Wir wollen im folgenden Mal auf die Implementierung eines Simaphores etwas genauer eingehen.
Die Programme, die wir für P und V benötigen, bilden selbst kritische Abschnitte und wir
wollen eben sehen, warum diese denn als kritische Abschnitte formuliert sein müssen.
Nehmen wir mal zunächst eine mögliche Implementierung der P-Operation.
Wir haben ja gesagt, die P-Operation erniedrigt den Simaforwert um 1.
Wenn zum Zeitpunkt der Erniedrung dieses Werts der Simaforwert 0 ist, dann soll der
Prozess in der P-Operation blockieren. Und das haben wir hier entsprechend
nachgebildet. Mit der Anweisung in 3 findet die Dekrementierung um 1 statt.
Dann überprüfen wir letztendlich, ob vor dem Dekrement der Simaforwert 0 war oder
andersherum nach dem Dekrement. Wenn dann der Simafor negativ ist, dann muss der
Prozess blockieren und die Blockade soll die Evade-Operation sein.
Wir sehen hier eben auch die Implementierungsvariante, die wir für die
Zähloperation verwendet haben. Wir zählen also immer und werden denn anhand von
negativen Werten des Simaforwerts feststellen, dass ein Prozess blockieren
muss in der P-Operation. Nun, jetzt unterstellen wir doch mal, dass diese
Operation von zwei Prozessen, wenigstens zwei Prozessen zugleich ausgeführt wird
und hinterfragen einfach, ob denn diese Operationsfolge dann immer noch so an
sich korrekt ist. Und wenn wir uns das genauer anschauen, dann werden wir eben
sehen, dass eine gleichzeitige Ausführung dieser P-Operation dazu führen kann, dass
mehr als ein Prozess eben diese P-Operation passieren kann, damit
möglicherweise auch selbst in einen kritischen Abschnitt eintreten kann,
der durch einen binären Simafor geschützt wäre. Mehr Prozesse, also
rübergehen über die P-Operation, als der Wert es eigentlich erlaubt. Wie ist es
möglich? Wir müssen einfach mal uns diese Anweisung in Zeile 3 ein
bisschen genauer anschauen. Diese arithmetische Operation hier wird
typischerweise von Prozessoren in mehr als einem Schritt ausgeführt.
Drei Schritte zum Beispiel sind hier nötig. Wir werden erstmal den Wert aus dem
Speicher lesen, der über diesen Zeigerwert hier angegeben ist. Damit haben
wir den Simaforwert in ein internes Register in die CPU geladen. Dann werden
wir in der CPU die arithmetische Operation ausführen. Das heißt, wir
dekrementieren den Wert in dem Register um 1 und dann schreiben wir
den Registerinhalt letztendlich zurück an diesen Simafor. Diese drei Schritte
finden nacheinander statt, sollten nacheinander stattfinden. Sie dürfen nicht
gleichzeitig überlappt stattfinden. Wenn wir uns mal vorstellen würden, dass zwei
Prozesse zugleich diese drei Schritte ausführen, dann können wir eine
Situation haben, dass beide Prozesse, die gleichzeitig hier über diese Zeile 3
rüberkommen, den Wert lesen aus dem Speicher, in ihr jeweiliges CPU-Register
kopieren. Beide Prozesse führen dann auf ihren jeweiligen Registerkopien die
Dekrementoperation aus und sie schreiben dann halt diesen
dekrementierten Wert zurück. Wenn anfangs in diesem Simaforwert eine 1
drin stand und zwei Prozesse kommen daher, dann würde das zur Folge haben,
dass am Ende beide Prozesse den Wert 0 letztendlich in diesen Simaforwert
zurückschreiben. Wir haben zwei Prozesse gehabt, die zählen wollten. Wir hätten
sozusagen 1 minus 2 minus 1 als Ergebnis in diesem Simafor erwarten dürfen. Das
ist aber nicht garantiert, wenn wir halt hier diese Anweisung 3 etwa so verstehen
würden als komplexe Anweisung. Die müssen wir so verstehen als komplexe
Anweisung und dass die dann von mehreren Prozessen gleichzeitig ausgeführt wird.
Das ist ein Problempunkt, den wir hier schon mal haben. Das kann aber auch
durchaus so sein, dass überhaupt kein Prozess hier rüberkommt. Nehmen wir doch mal an,
dass diese Anweisung hier sehr wohl von jedem einzelnen Prozess, die Anweisung in
Presenters
Zugänglich über
Offener Zugang
Dauer
00:20:16 Min
Aufnahmedatum
2020-11-27
Hochgeladen am
2020-11-27 16:09:34
Sprache
de-DE