Mein, mein liebe Leute, letztes Video zum Kapitel Coroutine und Fäden für die Betriebssystemvorlesung.
Was haben wir gemacht? Im letzten Kapitel haben wir uns angeguckt, wie man Coroutine implementieren
kann. Jetzt wollen wir mal angucken, wie man die Coroutine benutzen kann im Betriebssystem,
um jetzt Multitasking wirklich zusammenzubauen. Coroutine haben wir uns angeguckt, sind per se
eigentlich erstmal ein Sprachkonzept. Wir haben gesagt, wir definieren uns Funktionen und wir
können zwischen diesen Funktionen so verschränkt sozusagen hin und her hüpfen. Dieses hin und
her hüpfen ist dann so eine Art Multitasking, jetzt aber auf Sprachebene. Ich muss wirklich
hinschreiben, ich möchte von der eigenen Coroutine zu anderen rüber hüpfen. Gibt es typischerweise
in C, C++ und vielen anderen Sprachen nicht, aber wir haben jetzt hier für C oder C++ dieses
Resum uns gebastelt, was uns dann erlaubt auch in C, C++ Multitasking bzw. erst einmal Coroutine
benutzen zu können. Die meisten haben wahrscheinlich noch gar nicht so genau darüber nachgedacht,
aber wenn man sich das genau überlegt, dann wird man sehen oder noch mal anguckt, dann wird man sehen,
da ist nichts besonders dran eigentlich aus CPU Sicht. Diese Resum-Funktion ist aus CPU Sicht,
Wald- und Wiesenfunktion sind halt ein paar besondere Befehle drin, aber jetzt keine privilegierten.
Wir speichern ein paar Register auf dem Stack, wir kopieren was vom Stack hin und zurück,
wir machen ein Red, alles nicht aufregend, keine privilegierte Instruktionen dabei. Heißt,
das könnte man auch ganz normal in einer Anwendung machen. Wenn ihr mal Lust habt, könnt ihr euch
selber in einem Prozess noch mal Coroutine implementieren. Dann könnt ihr ganz normales
Wald- und Wiesen C-Programm, C++ Programmen mit Coroutine ausstatten. Was uns jetzt zum eigentlichen
Multitasking noch fehlt, ist die Kooperation, die man nämlich normalerweise nicht hat. Das erste
wäre natürlich alle Programme, die man jetzt Multitasking-mäßig ablaufen lassen möchte,
müssten jetzt als Coroutine implementiert sein. Also sozusagen die Main-Funktion ist schon eine
Coroutine von jedem Programm. Gut, das könnte man mal so definieren. Problem allerdings, und da hört
es dann definitiv in der Multitasking-Praxis auf, alle laufenden Anwendungen müssen sich
gegenseitig kennen. Warum? Die Idee ist ja, wir machen ein kooperatives Multitasking zurzeit.
Kooperativ im Sinne von, ja jede Anwendung, jede Coroutine muss immer mal wieder ein Resumen
aufrufen. Das heißt, da muss, so gefühlt, jede fünfte Instruktion im Programm muss ein Resumen
aufruf sein. Vergisst jemand diese Resumeninstruktion in sein Programm reinzuschreiben, dann geht es
schon in die Hose, dann ist nichts mehr mit Multitasking, dann läuft nur noch diese eine
Anwendung. Das ist das eine. Und das zweite, ja wenn wir das Resumen aufrufen, haben wir gesehen,
dann müssen wir als Parameter angeben, was dann resumed werden soll. Also welche Coroutine als
nächstes drankommen soll. Wenn jetzt in einem typischen Multitasking-Betriebssystem, Linux oder
so, natürlich dynamisch zur Laufzeit immer neue Anwendungen gestartet werden, Anwendungen terminieren
auch irgendwann, ja woher soll jetzt ein laufender Prozess wissen, welche anderen Coroutines es noch
gibt. Keine Ahnung. Also das wird noch ein Problem sein. Also erstens müssen die Anwendungen alle
kooperativ sein, sonst geht es schon mal gar nicht. Selbst wenn sie das eigentlich sein wollen, haben
sie das Problem, sie kennen eigentlich die anderen nebenher laufenden Coroutinen nicht. Von daher
können sie in dem Sinne dann gar nicht kooperativ sein. Also für ein echtes Mehrprogramm-Betriebssystem
ist das erstmal unrealistisch. Also kooperatives Multitasking funktioniert nicht.
Gut, was machen wir dann? Dann sagen wir, naja dann nehmen wir das Betriebssystem her. Das wird dafür
sorgen, dass die kooperativ sind, die Coroutinen, zweifelweise. Wie wir das machen, gucken wir uns
gleich an und wir definieren einfach alle Anwendungen, die wir starten, starten wir als Coroutine.
Also wenn so von der Idee her ein laufendes Programm, ein Fork aufruft, dann definieren wir
uns einfach eine neue Coroutine. Wir rufen ein Create für eine neue Coroutine auf. Und als
Continuation kopieren wir einfach den aktuellen Zustand von der Coroutine, die das Fork aufgerufen hat.
Kopieren wir rüber in die zweite Coroutine. Und dann laufen sozusagen zwei Coroutinen danach parallel.
Also wenn wir einen Prozess oder einen Faden erzeugen im späteren, dann werden wir stattdessen
eigentlich eine Coroutine instanzieren. Gut, zweite Punkt war, wie bringen wir dazu, Coroutinen
kooperativ zu sein? Ja, die Idee ist, wir unterbrechen sie einfach zwangsweise, nämlich schlicht mit dem
Timer Interrupt. Timer Interrupt, wenn der kommt, während eine Coroutine läuft, heißt die CPU
Presenters
Zugänglich über
Offener Zugang
Dauer
00:11:44 Min
Aufnahmedatum
2020-12-04
Hochgeladen am
2020-12-04 16:59:57
Sprache
de-DE
8. Kapitel der Vorlesung Betriebssysteme.