Bis jetzt konnten wir in unseren Benutzeranwendungen eine Synchronisation nur durch aktives Warten
oder Betreten der Epilog-Ebene erreichen, was wir so beispielsweise für die Ausgabe
verwendet haben.
In dieser Aufgabe führen wir Synchronisationsobjekte ein, wodurch die Anwendungen sich nun gegenseitig
über Ereignis informieren bzw. passiv darauf warten können.
Die Ausgabe kann nun mittels Simplifyings synchronisiert werden.
Außerdem bekommen die Threads die Möglichkeit, sich für eine bestimmte Zeit schlafen zu
legen.
Anschaulich bzw. eher anhörlich lässt sich das mittels dem PC Speaker demonstrieren,
indem man nacheinander verschiedene Töne abspielt, also beim Pit mittels Pulsdauermodulation
eine bestimmte Frequenz für eine gewisse Zeit einstellt und sich daraus dann eine Melodie
ergibt.
Sogegeben, der piepsende Systemlautsprecher ist aus gutem Grund nur noch ein historisches
Relikt und hat seit Jahrzehnten dank der standardmäßig integrierten Soundkarten keinerlei Relevanz
mehr.
Aber vor 30 Jahren wurde das insbesondere bei Spielen intensiv und durchaus sehr kreativ
genutzt.
Und uns kann es beim Erkennen von fehlerhaften Implementierungen helfen.
Die Umsetzung beginnen wir mit dem Simup Foren.
Neben der Ausgabe soll auch die Eingabe darüber synchronisiert werden.
Mittels Getkey kann ein Thread die nächste gedrückte Taste bekommen.
Sofern alle vorherigen Tasten bereits abgerufen wurden, wird auf den nächsten Tastendruck
gewartet.
Ein solches Warten soll auch zeitgesteuert möglich sein.
Wer will, kann dies mittels dem gezeigten PC Speaker testen.
Ein kurzer Beispielcode dafür ist in der Angabe gelistet.
Damit müssen wir uns nun gegen ein neues Problem wappnen.
Wenn gerade alle Threads schlafen, was soll denn dann ausgeführt werden?
In solchen Fällen müssen wir uns um den Leerlauf des Prozessors kümmern.
Und wer will, kann dabei auch stups zu einem Tickless-Körnel umbauen.
Damit die Benutzeranwendungen bequem die neue Funktionalität verwenden können, wollen wir
sie in Systemaufruf Schnittstellen kapseln, wie wir das bereits mit dem Guardet Scheduler
getan haben.
Konkret betrifft dies folglich die Tastatur, Semaphore sowie das zeitgesteuerte Schlafen.
Sowohl die Semaphore als auch die Bell, die das zeitgesteuerte Schlafen eines Threads
umsetzt, werden beide von Waiting Room abgeleitet, welche wiederum lediglich eine Que vom wardenden
Threads implementiert.
Für Semaphoren ist dies dabei offensichtlicher, dass wir hier potentiell mehrere wardende
Threads verwalten müssen.
Bei der Bell hingegen erscheint das am Anfang etwas unnötig, da dieses Objekt nur für
einen einzelnen Thread existiert, eben der sich gerade schlafen legen will.
Allerdings spart uns die Verwendung der gemeinsamen Basis-Klasse Waiting Room einiges an doppelten
Code, insbesondere im Scheduler, welcher sich nun auch mit dem neuen Zustand wardend rumschlagen
muss.
Dass wir zum Synchronisieren über Threads hinweg gemeinsame Semaphore-Objekte brauchen
und diese somit eher statisch allokieren, dürfte kaum überraschen.
Aber der Einsatz der Bell, dem Wecker, dürfte noch etwas unklar sein.
Eine Bell kann auch dynamisch erstellt werden, als temporäres Objekt auf dem Stack des Threads,
der sich damit selbst für eine gewisse Zeit schlafen legen will.
Alle aktiven Wecker-Objekte werden vom Bell-Ringer, zu Deutsch dem Glockner, in einer verketteten
Presenters
Zugänglich über
Offener Zugang
Dauer
00:08:43 Min
Aufnahmedatum
2020-08-25
Hochgeladen am
2020-10-16 18:56:34
Sprache
de-DE
Aufgabe 6 der Lehrveranstaltung Betriebssysteme.
Folien und Transkript zum Video.