24 - 10.7 Nichtsequentialität: Anhang Logische Synchronisation: bounded buffer [ID:23451]
50 von 108 angezeigt

Nun in dem Anhang hier möchte ich noch einmal auf den Ringpuffer, den wir vorhin betrachtet hatten,

zurückkommen und hier ein bisschen darstellen, wie man den ein bisschen anders synchronisiert

ablaufen lassen kann. Schwerpunktmäßig die logische Synchronisation, aber wir werden sehen,

dass nicht nur die allein verwendet wird, um den Puffer denn korrekt synchronisiert zu bekommen.

Die technische Grundlage dafür ist der sogenannte zählende Simaphor, der hier zum Einsatz kommt,

der nämlich im Sinne einer logischen Synchronisation verwendet wird. Der zählende

Simaphor wird hier oben definiert. Der wird dann zum Beispiel einen so einen zählenden Simaphor,

den wir verwenden namens Fri. Der wird mit der Anzahl der Elemente, die in diesem Puffer den

Platz haben können, dann vornitialisiert. Fri hat also den vornitialisierten Wert von 64. Und

dann haben wir einen zweiten Simaphor, einen zählenden, der hier verwendet wird, der praktisch anzeigt,

dass Daten verfügbar sind. Und initial, wenn der Puffer leer ist, dann sind eben noch keine Daten

in diesem Puffer drin. Ansonsten ist der Puffer immer noch 64 Elemente groß und wir starten mit

in- und out-Werten bei Null. Die Put-Operation, die Get-Operation haben wir jetzt ein bisschen

umgeschrieben. Da verwenden wir jetzt einen zählenden Simaphor als Einstieg P auf Free. Die

P-Operation hat die Eigenschaft, sie zählt sozusagen diesen Fri-Simaphor-Wert um eins

runter und sie würde denn praktisch den Prozess der P ausführt blockieren, wenn der Fri-Wert die

Zahl Null halt annimmt. Und da wir ja sehen, initial ist Fri, hat Fri den Wert 64, würde man

also jetzt erstmal vollkommen loslesen, solange man nicht davon ausgeht, dass eine Get-Operation

parallel stattfindet. Wenn man mindestens 64 mal Put machen könnte, bevor denn der 65. Prozess

halt blockieren würde. Dann haben wir eine Aktion, die hier, die sorgt für das Eintragen des

Elements in den Puffer. Hier werden wir die Fetch-and-Dead-Operation verwenden, die wir

schon kennengelernt haben. Und am Ende, wenn wir eingetragen haben, werden wir eine V-Operation

ausführen, die hier dafür Sorge trägt, dass eine Signalisierung von verfügbaren,

mindestens eines verfügbaren Datums angezeigt wird. Denn diese Signalisierung hier benötigen wir,

um ein potentiell im Get-blockierten Prozess halt zu deblockieren. Hier in der Get-Operation haben

wir ein gleiches Muster wie vorne auch. Wir haben eine P-Operation, die steuert praktisch,

wie viele Prozesse letztendlich das Get jetzt so gleich machen dürfen. Nämlich genau so viele

Prozesse dürfen gleichzeitig ein Get machen, wie die Anzahl des zählenden Simaphores Data vorgibt.

Denn das ist dann die Anzahl der im Puffer gespeicherten Elemente letztendlich. Solange

denn also der Data-Wert null ist, würde hier der Prozess blockieren, der die Get-Operation

ausführt. Initial ist Data null und das würde bedeuten, dass Initial im Get ein Prozess

natürlich dann blockieren wird. Und damit kann es eben doch keinen Pufferunterlauf geben. Hier oben

würde die Blockierung bei Free dann stattfinden, wenn wir den Puffer komplett gefüllt haben. Und

damit kann es keinen Überlauf geben. Das V-Data würde also jetzt hier in der Zeile 9 eine

Signalisierung machen, eine logische Synchronisation bewirken mit dem Prozess, der im Get-Potentiell

hier in der Zeile 13 blockiert und würde diesen Prozess möglicherweise freistellen, wenn hier

jemand ist, der warten würde. Die P-Operation, die hier oben zur Blockierung eines Prozesses führt,

ist gepaart mit der V-Operation, die wir heute in Zeile 15 haben. Und das V hier würde dazu führen,

dass ein auf Free wartender Prozess deblockiert wird, wenn die Get-Operation hier zum Ende gekommen

ist. Das V signalisiert also, dass wieder ein freier Pufferplatz verfügbar ist, mindestens ein

freier. Dann haben wir hier zwischen dem P und V innerhalb der Get-Operation, also in der Zeile 14,

eben die Pufferoperation, wo man Element aus dem Puffer halt rausholt. Und da verwenden wir auch

wieder die Fetch-And-Get-Operation. Im Vergleich zu dem, was wir vorher gesehen haben, verwenden wir

jetzt hier nicht Signalisierungsoperationen, we await, und cause und die Abfrage einer Wartbedingungen,

sondern wir verwenden halt sogenannte Simaphore, zählende Simaphore, die dann sozusagen diesen

Kontrollvorgang für die Prozesse, nämlich wann ein Prozess jetzt blockiert und wann ein Prozess

dann freigestellt wird, dann übernehmen. Wir werden diesen Simaphore, die P und V-Operation,

und was sich dahinter diesem Namen, der nur verbirgt, werden wir im weiteren Verlauf schon noch

kennenlernen. Das ist der begrenzte Puffer, der bounded buffer, der Klassiker sozusagen. Der wird

typischerweise mit diesen Operationen, mit solchen Simaphorenoperationen dann halt hier

Teil eines Kapitels:
10.1 Nichtsequentialität

Zugänglich über

Offener Zugang

Dauer

00:12:37 Min

Aufnahmedatum

2020-11-10

Hochgeladen am

2020-11-11 01:27:36

Sprache

de-DE

Einbetten
Wordpress FAU Plugin
iFrame
Teilen