Moin Moin liebe Leute, willkommen zum nächsten Video Betriebssysteme. Nächster Teil, nächstes
Kapitel, nämlich Coroutine und Fäden. Was wollen wir da machen? Ja, wir wollen uns mal angucken.
Kontrollflussabstraktion brauchen wir, um eine Prozessverwaltung bauen zu können. Jetzt kommt
nämlich so der spannende Teil, sage ich mal, vom Betriebssystem, nämlich das Multitasking. Ja,
was machen wir da? Gucken wir uns erstmal an, wie man Multitasking so ganz grob mal hinkriegen
könnte. Was wir machen wollen, wir wollen eigentlich, dass Funktionen f und Funktion g hier
zum Beispiel sozusagen quasi parallel laufen sollen. Also das erste sollte man das f, das f
doppelt Punkt eins ausgeben, dann sollte das g, das g doppelt Punkt a ausgeben, f2, gb, f3, gc und dann
soll das Programm terminieren. Also dieses Programm, diese zwei Unterprogramme sollen
verschränkt ablaufen. Jo, wie könnte man das mal angehen? Erste Idee, man ruft einfach f auf und
danach g, wisst ihr alle, das tut nicht. Das liefert dann erstmal alle f-Werte und dann alle g-Werte,
das war es nicht. Okay, anderer Versuch, wir rufen nur f von Main aus auf und immer nach jeder
Aufgabe das g, kann ich euch schnell vorstellen, geht auch nicht. Na, da kommt zwar das f1, f2, f3,
dazwischen kommen immer die gs, aber es kommen alle g-Ausgaben jeweils zwischen den Aufrufen.
Hier geht auch nicht. Okay, die dritte Version, auf die man möglicherweise noch kommen könnte,
ist also wenn man dann f aufgerufen hat von Main, dass man von da aus sagt, ja jetzt soll doch mal
bitteschön g die Ausgabe machen und wenn g eine Ausgabe gemacht hat, dann ist doch f wieder dran.
Ja, das ist eine endlosere Äquation, weil das f, was ich hier aufrufe, jetzt nicht da weitermacht,
sondern wieder am Anfang neu aufgerufen wird. Führt letztendlich dazu, dass f und g sich ständig
gegenseitig aufrufen und auch nie wieder zurückkehren. Wenn sie nie zurückkehren, dann läuft irgendwann
der Stack über mit dem Ergebnis, ihr seht hier, SegmentationFault. Da crasht einfach das Programm
dann irgendwann. Jetzt kommt eine Version, die funktioniert, ich sag mal so fast. Also in diesem
Beispiel mit dem passenden Compiler tut sie das, was wir wollen. Wie funktioniert die? Also wir
haben hier unser f, wir haben unser g und was machen die Funktion jeweils, wenn sie gelaufen sind,
also sprich, wenn sie ihre Ausgabe gemacht haben. Was machen sie dann? Ja, sie merken sich, wo es
weitergehen soll. Ihr seht hier eine ganz komische Konstruktion, die meisten von euch werden die nie
gesehen haben bisher. Ich habe sie, muss ich gestehen, auch noch nie benutzt außerhalb von
diesem Beispiel hier. Aber für dieses Beispiel war es ganz nützlich. Was ist das? Ja, das ist eine
extension vom GNU C Compiler, nämlich, dass man sich von Labels die Adressen nehmen kann. Und umgekehrt
bei einem Goto kann ich so eine geholte Adresse dann wieder verwenden, um dahin zu springen. Also
das f hier, ihr seht sie unten als Definition. Das f ist jetzt ein Zeiger auf eine Funktion. Also
wenn ich mir hier f hole, dann hole ich mir einen Zeiger auf eine Funktion. Also Zeiger auf einen
Punkt in der Funktion, wo es weitergehen soll. Wenn ich das jetzt entsprechend initialisiere, f zeigt
auf den Anfang dieser Funktion f statt, g zeigt auf den Anfang von dieser Funktion g und wenn ich
dann f starte, okay dann ist erstmal klar, dass das f natürlich hier erstmal die Ausgabe macht.
Dann merkt sich das f jetzt, wo es fortgesetzt werden will, nämlich da und springt dahin, wo g
hin zeigt. g hat man vorher initialisiert mit g statt, also springt er von hier dahin und macht
seine Ausgabe. Dann ändert er diesen g Zeiger. Er sagt, wenn ich wieder aufgerufen werde über
diesen Zeiger, dann soll es doch bei l1 weitergehen. Und dann springt er wieder rüber zu f, nämlich zu
dem Punkt, den wir vorher in f gespeichert haben. Vorher haben wir in f gespeichert die Adresse von
diesem l1, also springen wir dahin wieder zurück. Heißt, dass f macht hier seine Ausgabe, merkt sich
für den nächsten Rücksprung, wo es weitergehen soll, nämlich da und springt zurück zu der Stelle,
die g sich gemerkt hat, sprich nach dahin und so weiter. Wenn man sich das anguckt,
das funktioniert tatsächlich. Allerdings, also Warnung, hier steht extra gcc 2.95 minus f
um mit frame pointer. Damit haben wir es mal getestet, vor einer Weile damit ging es.
Das funktioniert, da bin ich mir ziemlich sicher, nur sehr zufällig mit einem entsprechenden
Compiler. Aber es funktioniert definitiv, kann man im Prinzip so machen. Jo, was, kleines Fazit
draus, Funktionsaufrufe selber tun nicht das, was wir wollen. Also C++, was die bieten als
Sprachkonstrukt taugt uns nicht. Wenn ich eine Funktion aufrufe, dann läuft die bis zum Ende
durch. Die hört nicht auf halben Wege auf und lässt sich später wieder neu starten. Das geht nicht.
Presenters
Zugänglich über
Offener Zugang
Dauer
00:09:21 Min
Aufnahmedatum
2020-11-30
Hochgeladen am
2020-12-04 16:20:13
Sprache
de-DE
8. Kapitel der Vorlesung Betriebssysteme.