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
Presenters
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