Wenn mehrere Threads dieselben Betriebsmittel verwenden, welche nur exklusiv benutzt werden
können, müssen sie sich synchronisieren.
Mittels gegenseitigem Ausschluss wird dabei verhindert, dass mehrere Fäden denselben
kritischen Abschnitt betreten.
Wie sieht das in Stubs aus?
Wir haben doch mit der Umlaufsperre ein kreiseln des Warten implementiert.
Sowohl Ticket als auch Spinlock bieten dazu die Methoden Lock zum Sperren und Unlock zum
Entsperren des kritischen Abschnitts an.
Als Beispiel lassen wir mal im Eincam-Betrieb drei Anwendungen einem wechselseitigen Ausschluss
verwenden.
Zu Beginn befinden sich auch alle noch in der Bereitschaftsliste.
Die erste Anwendung wird entnommen und die Bearbeitung angefangen.
Sie ruft die Sperroperation auf dem Utex auf und betritt damit den kritischen Abschnitt.
Bei der Abarbeitung kann es nun jedoch vorkommen, dass unsere Zeitscheibe abläuft, während
wir noch in diesem Abschnitt sind.
Der Timer Interrupt also veranlasst, dass wir rausgeschedult werden.
Dann wird mit App 2 die nächste Anwendung aus der Bereitschaftsliste entnommen und ausgeführt.
Diese versucht ebenfalls den kritischen Abschnitt zu betreten, da aber Anwendung einzig noch
darin befindet und entsprechend den Lock hält, wird sie aktiv warten.
Und zwar so lange, bis die Zeitscheibe abgelaufen ist.
Sobald auch hier die Timer Interbrechen kommt, wird sie unverrichteter Dinge wieder in die
Bereitschaftsliste gelegt, die nächste Anwendung entnommen und ihr die Kontrolle übergeben.
Und das Spiel wiederholt sich.
Ein Betreten des kritischen Abschnitts ist zurzeit nicht möglich, es wird aktiv gewartet.
Und zwar wieder die ganze Zeitscheibe, bis sie wieder rausgeschedult wird und endlich
App 1 wieder zum Zuge kommt, den kritischen Abschnitt fertig stellen kann und den Utex
freigibt.
Wir haben also einen Großteil unserer Zeit mit aktiven Warten verbracht, ohne dass wir
währenddessen irgendeinen Fortschritt haben hätten können, haben somit im Endeffekt
nur das Zimmer geheizt.
Wie geht das besser?
Nun, wir könnten eine harte Synchronisation verwenden, eine Art deaktivierende Unterbrechungen,
aber weniger umfassend, nur auf den Scheduler beschränkt, dass dieser uns nicht innerhalb
eines kritischen Abschnitts zurück in die Bereitschaftsliste schickt.
Wie könnten wir das implementieren?
Eine Möglichkeit wäre das temporäre Aussetzen des präemptiven Schedulings, beispielsweise
indem wir die Timer-Unterbrechungen blockieren.
Oder wir erweitern den Scheduler, so dass wir ihn über die Abarbeitung kritischer
Abschnitte informieren können und er währenddessen auf einem Fadenwechsel verzichtet.
Zudem haben wir natürlich noch unsere Epilog-Ebene, könnten den kritischen Abschnitt einfach dort
abarbeiten, Timer-Epilogie werden dadurch erst beim Verlassen ausgeführt, wir werden
also davor nicht verdrängt.
Diese Varianten funktionieren und sind zudem auch vergleichsweise einfach umzusetzen.
Leider haben sie auch systemweite Auswirkungen, wir verzögern unter Umständen höher priori
Kontrollflüsse und führen das außerdem immer vorbeugend aus.
Gibt es da nicht was besseres ohne diese Probleme?
Wie wäre es mit einem passiven Warten, dass wir also die blockierten Threads aus dem Scheduler
nehmen, während der betreffende Abschnitt belegt ist?
Bis jetzt kennt unser Scheduler zwei Zustände, Active für den aktuell laufenden Thread und
Ready für die Threads in der Bereitschaftsliste.
Presenters
Zugänglich über
Offener Zugang
Dauer
00:06:41 Min
Aufnahmedatum
2020-08-26
Hochgeladen am
2021-09-20 19:16:36
Sprache
de-DE
Methoden zum gegenseitigen Ausschluss für Aufgabe 6 der Lehrveranstaltung Betriebssysteme.
Folien und Transkript zum Video.