Betriebssysteme, Prozesse und Nebenläufigkeit
Du hörst Musik, lädst eine Datei herunter und tippst in einem Editor. Dein Prozessor hat vielleicht vier Kerne, aber es laufen weit mehr Programme. Wer entscheidet, welches wann rechnet? Wie verhindert der Rechner, dass der Editor den Speicher des Browsers überschreibt? Und was geschieht, wenn zwei Programme dieselbe Zahl ändern oder jedes auf das andere wartet?
Das Betriebssystem beantwortet die ersten Fragen. Die letzten führen zur Nebenläufigkeit, in der Fehler schwer zu finden sind.
Aufgaben eines Betriebssystems und Kernel
Ein Betriebssystem ist die Systemsoftware, die Anwendungen den Zugriff auf die Hardware gibt und die Betriebsmittel verwaltet: Prozessorzeit, Speicher, Geräte, Dateien. Sein Kern heißt Kernel. Er läuft im privilegierten Kernelmodus und darf alle Befehle und Speicherbereiche nutzen. Anwendungen laufen im Benutzermodus mit eingeschränkten Rechten. Will eine Anwendung eine Datei lesen, ruft sie den Kernel über einen Systemaufruf an, der die Anfrage prüft und ausführt.
Datei-, Speicher-, Prozess-, Benutzer- und Rechteverwaltung
| Verwaltung | Aufgabe |
|---|---|
| Prozessverwaltung | Prozesse anlegen und beenden, dem Prozessor der Reihe nach zuteilen |
| Speicherverwaltung | Hauptspeicher verteilen, jedem Prozess einen eigenen Adressraum geben, Teile auslagern (virtueller Speicher) |
| Dateiverwaltung | Daten in Dateien und Verzeichnissen ablegen (Dateisystem) |
| Benutzerverwaltung | Benutzerkonten und Anmeldung |
| Rechteverwaltung | festlegen, wer was lesen, schreiben oder ausführen darf |
Bei Unix-ähnlichen Systemen hat jede Datei Rechte für Besitzer, Gruppe und alle anderen, je als Lesen (r, Wert 4), Schreiben (w, 2) und Ausführen (x, 1). Die Rechte bedeuten: Besitzer rwx (4 + 2 + 1 = 7), Gruppe r-x (4 + 1 = 5), andere nichts (0), zusammen 750.
Prozesse und Prozesszustände
Ein Programm ist eine Datei mit Befehlen. Ein Prozess ist ein Programm in Ausführung, mit eigenem Adressraum, Befehlszähler und Registerinhalten. Das Betriebssystem führt für jeden Prozess einen Prozesskontrollblock mit Zustand und Registern. Ein Prozess ist in einem von drei Zuständen:
- bereit: Er könnte rechnen und wartet auf einen freien Prozessor.
- rechnend: Er hat einen Prozessor. Je Kern rechnet höchstens einer.
- blockiert: Er wartet auf ein Ereignis, etwa eine Eingabe.
| Von | Nach | Auslöser |
|---|---|---|
| bereit | rechnend | Der Scheduler teilt den Prozessor zu. |
| rechnend | bereit | Die Zeitscheibe ist abgelaufen oder ein wichtigerer Prozess verdrängt ihn. |
| rechnend | blockiert | Der Prozess wartet auf ein Ereignis. |
| blockiert | bereit | Das Ereignis ist eingetreten. |
Ein blockierter Prozess wird nie direkt rechnend, er muss erst bereit werden.
Scheduling
Der Scheduler wählt aus den bereiten Prozessen den nächsten für den Prozessor. Ein Verfahren ist verdrängend, wenn es einem rechnenden Prozess den Prozessor entziehen darf.
- FCFS (first come, first served): Die Prozesse laufen in der Reihenfolge ihres Eintreffens bis zum Ende. Ein langer Prozess lässt alle kurzen warten. Nicht verdrängend.
- SJF (shortest job first): Der Prozess mit der kürzesten Rechenzeit kommt zuerst. Das gibt die kleinste mittlere Wartezeit, braucht aber die Rechenzeit im Voraus.
- Round Robin: Jeder Prozess bekommt reihum eine Zeitscheibe, danach reiht er sich hinten ein. Verdrängend, gut für interaktive Programme.
- Prioritäten: Die höchste Priorität läuft zuerst. Niedrige können dauernd übergangen werden (verhungern).
Die Wartezeit eines Prozesses ist die Zeit, die er bereit ist, ohne zu rechnen.
Drei Prozesse im Vergleich
Drei Prozesse im Vergleich
P1, P2 und P3 treffen zum Zeitpunkt 0 ein, in dieser Reihenfolge, mit den Rechenzeiten 6, 3 und 1. Bestimme die mittlere Wartezeit bei FCFS, SJF und Round Robin mit Zeitscheibe 2.
FCFS: P1 von 0 bis 6, P2 bis 9, P3 bis 10. SJF: P3 von 0 bis 1, P2 bis 4, P1 bis 10. Round Robin: P1 0 bis 2, P2 2 bis 4, P3 4 bis 5 (fertig), P1 5 bis 7, P2 7 bis 8 (fertig), P1 8 bis 10. Wartezeit = Ende minus Rechenzeit.
| Verfahren | P1 fertig | P2 fertig | P3 fertig | mittlere Wartezeit |
|---|---|---|---|---|
| FCFS | 6 | 9 | 10 | (0 + 6 + 9) : 3 = 5 |
| SJF | 10 | 4 | 1 | (4 + 1 + 0) : 3 ≈ 1,67 |
| Round Robin | 10 | 8 | 5 | (4 + 5 + 4) : 3 ≈ 4,33 |
SJF hat die kleinste mittlere Wartezeit. Round Robin liegt dazwischen, dafür kommt jeder Prozess früh zum ersten Mal dran.
Threads, Nebenläufigkeit und kritischer Abschnitt
Ein Thread ist ein Ausführungsstrang innerhalb eines Prozesses. Alle Threads eines Prozesses teilen sich Code und Daten im Speicher, jeder hat aber eigene Register, einen eigenen Befehlszähler und einen eigenen Stapel. Nebenläufig heißt: Aktivitäten schreiten unabhängig voran, ihre Schritte sind beliebig verschachtelt. Parallel heißt: Sie laufen wirklich gleichzeitig auf mehreren Kernen. Nebenläufigkeit gibt es auch auf einem Kern.
Gefährlich ist der gemeinsame Speicher. Ein kritischer Abschnitt ist ein Programmstück, das auf gemeinsame Daten zugreift und nur von einem Thread zur Zeit ausgeführt werden darf (gegenseitiger Ausschluss). Hängt das Ergebnis von der zufälligen Reihenfolge der Schritte ab, liegt ein Wettlauf (race condition) vor.
Eine verlorene Erhöhung
Eine verlorene Erhöhung
Zwei Threads T1 und T2 erhöhen dieselbe Variable z (Anfangswert 5) je um 1. Jeder führt LOAD z, AKK := AKK + 1 und STORE z aus, mit eigenem Akkumulator. Zeige eine Reihenfolge, bei der z am Ende 6 statt 7 ist.
| Schritt | Thread | Befehl | AKK des Threads | z danach |
|---|---|---|---|---|
| 1 | T1 | LOAD z | 5 | 5 |
| 2 | T2 | LOAD z | 5 | 5 |
| 3 | T1 | AKK := AKK + 1 | 6 | 5 |
| 4 | T2 | AKK := AKK + 1 | 6 | 5 |
| 5 | T1 | STORE z | 6 | 6 |
| 6 | T2 | STORE z | 6 | 6 |
Beide lasen den alten Wert 5, eine Erhöhung ging verloren. Läuft T1 ganz vor T2, ist z = 7. Der Fehler zeigt sich nur bei manchen Reihenfolgen. Lesen, Erhöhen und Schreiben muss ein kritischer Abschnitt sein.
Synchronisation: Semaphor und Monitor
Ein Semaphor (nach Dijkstra) ist eine ganze Zahl s mit zwei unteilbaren Operationen. : Ist , wird s um 1 vermindert, sonst wird der Thread blockiert, bis ein anderer ausführt. : Wartet ein Thread, wird er geweckt, sonst wird s um 1 erhöht. Mit Anfangswert 1 (Mutex) sichert ein Semaphor einen kritischen Abschnitt: davor, danach. Mit Anfangswert n zählt er n gleichartige Betriebsmittel.
Ein Monitor fasst gemeinsame Daten und die Methoden, die sie ändern, in einer Einheit zusammen. In ihr ist höchstens ein Thread aktiv, das regelt die Sprache. Ein Thread kann im Monitor auf eine Bedingung warten (wait) und wird von einem anderen geweckt (notify). In Java entspricht dem .
Verklemmung
Eine Verklemmung (Deadlock) liegt vor, wenn Threads aufeinander warten und keiner weiterkommt. Das geschieht nur, wenn vier Bedingungen zugleich gelten: Ein Betriebsmittel ist nur einzeln benutzbar (gegenseitiger Ausschluss), ein Thread hält eines und wartet auf ein weiteres, kein Betriebsmittel lässt sich entziehen, und die Wartenden bilden einen Kreis. Schließt man eine aus, ist keine Verklemmung möglich. Üblich: Alle fordern Betriebsmittel in derselben festen Reihenfolge an.
Zwei Sperren in verschiedener Reihenfolge
Zwei Sperren in verschiedener Reihenfolge
Die Semaphore x und y haben den Anfangswert 1. Thread A führt , dann aus, Thread B führt , dann aus. Wie entsteht eine Verklemmung, und wie verhindert man sie?
A führt P(x) aus (x ist 0), dann B P(y) (y ist 0). Nun blockiert A bei P(y), und B blockiert bei P(x). Jeder wartet auf einen Semaphor, den der andere hält: ein Kreis.
Fordern beide erst x, dann y an, entsteht kein Kreis. Der zweite Thread blockiert schon bei P(x) und hält noch nichts.
Erzeuger-Verbraucher und Philosophenproblem
Beim Erzeuger-Verbraucher-Problem legt ein Erzeuger Elemente in einen Puffer mit n Plätzen, ein Verbraucher entnimmt sie. Der Erzeuger wartet bei vollem, der Verbraucher bei leerem Puffer, und nur einer darf zur Zeit auf den Puffer zugreifen. Drei Semaphore genügen: frei (Anfangswert n), belegt (0) und mutex (1).
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 1 | 0 | Erzeuger, wiederholt: |
| 2 | 1 | , dann |
| 3 | 1 | Element in den Puffer legen |
| 4 | 1 | , dann |
| 5 | 0 | Verbraucher, wiederholt: |
| 6 | 1 | , dann |
| 7 | 1 | Element aus dem Puffer nehmen |
| 8 | 1 | , dann |
Beim Philosophenproblem sitzen fünf Philosophen an einem runden Tisch, zwischen je zwei Tellern liegt eine Gabel. Zum Essen braucht einer die Gabel links und rechts. Nimmt jeder zuerst die linke, hält jeder eine und wartet auf die rechte: Verklemmung. Lösungen: Die Gabeln werden nummeriert und jeder nimmt zuerst die mit der kleineren Nummer (kein Kreis), oder höchstens vier Philosophen sitzen gleichzeitig am Tisch.
Wettlauf nur bei mehreren Kernen
Wettlauf nur bei mehreren Kernen
"Mein Rechner hat nur einen Kern, also kann es keinen Wettlauf geben."
Auch auf einem Kern wechselt das Betriebssystem jederzeit zwischen Threads, etwa zwischen LOAD und STORE. Die Reihenfolge der Schritte ist dann genauso zufällig.
Zusammenfassung
Das Betriebssystem verwaltet Prozesse, Speicher, Dateien, Benutzer und Rechte. Der Kernel läuft im privilegierten Modus, Anwendungen rufen ihn über Systemaufrufe.
Ein Prozess ist bereit, rechnend oder blockiert. Der Scheduler wählt den nächsten, etwa nach FCFS, SJF, Round Robin oder Priorität.
Threads teilen sich den Speicher eines Prozesses. Nebenläufig heißt verschachtelt, parallel heißt gleichzeitig.
Gemeinsame Daten brauchen gegenseitigen Ausschluss, sonst entsteht ein Wettlauf. Semaphor (P und V) und Monitor sichern kritische Abschnitte.
Eine Verklemmung braucht vier Bedingungen zugleich. Erzeuger-Verbraucher und Philosophen sind die klassischen Synchronisationsprobleme.
Übungen
Ein rechnender Prozess wartet auf eine Eingabe von der Tastatur. In welchen Zustand wechselt er?
Drei Prozesse mit den Rechenzeiten 5, 2 und 2 treffen zum Zeitpunkt 0 ein, in dieser Reihenfolge, und laufen nach FCFS. Wie groß ist die mittlere Wartezeit?
Ein Semaphor s hat den Wert 0. Ein Thread führt P(s) aus. Was geschieht?
Eine Datei hat die Unix-Rechte rw-r----- (Besitzer rw-, Gruppe r--, andere ---). Welche dreistellige Zahl ergibt das? Lesen zählt 4, Schreiben 2, Ausführen 1.
Nenne die vier Bedingungen für eine Verklemmung und erkläre, welche die Nummerierung der Gabeln beim Philosophenproblem aufhebt.