Betriebssysteme: Das Wichtigste in Kürze Roland Weber 2021-02-21 - DHBW ...

Die Seite wird erstellt Aaron Schütze
 
WEITER LESEN
Betriebssysteme: Das Wichtigste in Kürze
                                     Roland Weber
                                      2021-02-21

1 Hardware
Systembus (engl.: system bus)
Der Systembus bildet das Rückgrat eines Rechners. Daran angeschlossen sind Prozessoren (CPUs),
Hauptspeicher (RAM) und weitere Bausteine wie Peripheriechips, Grafikprozessoren (GPUs) oder
Koprozessoren. Prozessoren und andere aktive Komponenten legen Adressen auf den Systembus.
Der Hauptspeicher und andere passive Komponenten reagieren auf bestimmte Adressen. Kompo-
nenten setzen ein Unterbrechungssignal, um Prozessoren auf sich aufmerksam zu machen. Das ist
die logische Sicht eines Systementwicklers, auch wenn moderne Hardware anders funktioniert.

Prozessor, CPU (engl.: processor, central processing unit)
Ein Prozessor liest Maschinenbefehle aus dem Hauptspeicher und führt sie aus. Jeder Prozessor
hat einen Satz von Registern. Befehle verändert die Registerinhalte und greifen über den System-
bus auf Hauptspeicher und angeschlossene Bausteine zu. Zwischen Prozessor und Systembus kann
eine MMU liegen, die der Prozessor kontrolliert. Unterbrechungen veranlassen den Prozessor, be-
stimmte Befehle auszuführen.

Hauptspeicher, RAM (engl.: main memory, random access memory)
Der Hauptspeicher enthält den Code und die meisten Daten, mit denen die Prozessoren arbeiten.
Er ist an den Systembus angeschlossen und reagiert auf viele Adressen. Bei Lesezugriffen lie-
fert er den Speicherinhalt einer Adresse, bei Schreibzugriffen übernimmt er einen neuen Wert als
Speicherinhalt. Der Hauptspeicher ist flüchtig, ohne Strom geht sein Inhalt verloren.

Adressübersetzung, MMU (engl.: memory management unit)
Die MMU sitzt zwischen einem Prozessor und dem Systembus. Sie übersetzt logische Adressen,
mit denen der Prozessor arbeitet, in physische Adressen auf dem Systembus. Jeder Prozessor hat
eine eigene MMU. Die notwendigen Übersetzungstabellen liegen im Hauptspeicher und können
von mehreren MMUs gleichzeitig genutzt werden. Der Prozessor bestimmt, mit welcher Überset-
zungstabelle seine MMU arbeitet.

Zeitgeber (engl.: timer)
Der Zeitgeber ist ein automatisches Zählregister im Prozessor. Damit kann der Prozessor zeitge-
steuerte Unterbrechungen mit einer Genauigkeit von Millisekunden bei sich auslösen.

Peripheriechips
Peripheriechips übernehmen die Kommunikation mit angeschlossenen Geräten und Netzwerken.
Auf einer Seite hängen sie am Systembus, auf der anderen bieten sie Anschlüsse für die Periphe-
rie. Prozessoren beauftragen Peripheriechips, Daten zwischen Hauptspeicher und Peripherie zu
übertragen, oder sie lesen und schreiben Datenpuffer in den Chips. Peripheriechips melden mit
Unterbrechungssignalen, wenn Aufträge erledigt sind oder Probleme auftauchen.

2021-02-21                                 BS:DaWiK                                           1
2 Programmiermodell
Register (engl.: register)
Register sind Speicherplätze mit Sonderfunktionen, außerhalb des Hauptspeichers, in Prozesso-
ren und anderen Bausteinen am Systembus. Register in einem Prozessor enthalten Adressen und
Daten für Berechnungen oder steuern Systemfunktionen wie den Betriebsmodus des Prozessors.
Der Zugriff erfolgt direkt über Prozessorbefehle. Register in einer MMU definieren die aktive
Übersetzungstabelle. Der Zugriff erfolgt ebenfalls über Befehle des Prozessors, für den die MMU
zuständig ist. Register in Peripheriebausteinen enthalten Statusinformationen und nehmen Aufträ-
ge entgegen. Der Zugriff erfolgt über Adressen auf dem Systembus. Einstellungen der MMU oder
spezielle Befehle stellen sicher, dass diese Zugriffe an Speichercaches vorbeigehen.

Betriebsmodus eines Prozessors (engl.: processor mode)
Moderne Prozessoren unterstützen mindestens zwei Betriebsmodi, einen Anwendungs- und einen
Systemmodus. Im Anwendungsmodus (engl.: user mode) kann der Befehlsstrom nur einen Teil
der Register benutzen und die MMU nicht umprogrammieren. Im Systemmodus (engl.: supervisor
mode, kernel mode, privileged mode) hat er vollen Zugriff auf die Register von Prozessor und
MMU. Der Wechsel vom Anwendungs- in den Systemmodus erfolgt durch eine Unterbrechung.

Befehlsstrom (engl.: instruction stream)
Der Prozessor liest Befehle nacheinander aus dem Speicher und führt sie aus. Ein Register, der
Befehlszeiger, enthält die Adresse des nächsten Befehls. Es wird automatisch erhöht oder durch
Sprungbefehle verändert. Bei Aufruf eines Unterprogramms landet der Inhalt des Befehlszeigers
als Rücksprungadresse in einem Register oder auf dem Stapel. Die Folge der auf diese Weise
ausgeführten Befehle ist ein Befehlsstrom.

Unterbrechung (engl.: interrupt)
Bei einer Unterbrechung stoppt der Prozessor den aktuellen Befehlsstrom, aktiviert den Systemmo-
dus und beginnt eine Unterbrechungsbehandlung. Das ist ebenfalls ein Befehlsstrom, dessen Start-
adresse von der Art der Unterbrechung abhängt. Am Ende springt die Unterbrechungsbehandlung
zurück zum unterbrochenen oder zu einem anderen Befehlsstrom. Auslöser von Unterbrechungen
sind unter anderem Peripheriechips, MMU und Zeitgeber. Der laufende Befehlsstrom kann eine
Unterbrechung explizit auslösen (engl.: software interrupt), um Systemfunktionen aufzurufen.

Rechenumgebung
Die Rechenumgebung umfasst diejenigen Register des Prozessors, in welche ein Befehlsstrom im
Anwendungsmodus schreiben darf. Insbesondere gehören dazu der Befehlszeiger und der Stapel-
zeiger. Compiler erzeugen Code, der nur mit den Registern der Rechenumgebung arbeitet.

Ablaufumgebung
Die Ablaufumgebung umfasst Register des Prozessors und der MMU, die ein Befehlsstrom im
Anwendungsmodus nicht verändern darf. Insbesondere gehören dazu die Einstellungen der MMU.
Ein Befehlsstrom im Systemmodus kann die Ablaufumgebung anpassen. Register, welche auf die
Ausführung eines Befehlsstroms keinen Einfluss haben oder deren Werte sich nie ändern, zählen
nicht zur Ablaufumgebung.

2021-02-21                                 BS:DaWiK                                           2
3 Programm
Segment (engl.: segment)
Programme benutzen zur Laufzeit mehrere zusammenhängende Speicherbereiche, die Segmente.
Segmente mit statischer Größe definiert das Programm. Für dynamisch verwaltete Daten gibt es
eigene Segmente, insbesondere den Stapel und die Halde. Diese stellt das Betriebssystem bereit.
Typische Segmente statischer Größe sind:
  1. Code (engl.: code, program text)
     Maschinenbefehle, die der Prozessor ausführen kann.
  2. Statische Daten (engl.: data)
     Änderbare Daten fester Größe, zum Teil initialisiert.
  3. Konstanten (engl.: read–only data)
     Nicht veränderbare Daten, initialisiert.
Stapel, Keller (engl.: stack)
Ein Befehlsstrom braucht einen Stapel für verschachtelte Aufrufe. Jede aufgerufene Funktion be-
legt einen Teil des Stapels (engl.: stack frame) für lokale Variablen und die Rücksprungadresse.
Mit der Rückkehr zum Aufrufer wird dieser Teil des Stapels wieder frei. Beim Start eines Pro-
gramms stellt das Betriebssystem ein Segment für den Stapel des ersten Prozesses bereit. Woher
der Stapel für weitere Prozesse im gleichen Adressraum kommt, ist systemabhängig.
Halde (engl.: heap)
Die Halde ist ein dynamisch verwalteter Speicherbereich. Im Gegensatz zum Stapel überleben
Objekte auf der Halde das Ende von Funktionsaufrufen. Alle Prozesse in einem Adressraum ver-
wenden die gleiche Halde. Beim Start eines Programms wird ein Segment für die Halde angelegt.
Bibliotheksfunktionen verwalten die Halde und vergrößern bei Bedarf das Segment.
Ausführbare Datei (engl.: executable)
Eine ausführbare Datei definiert die Größe und den Inhalt der statischen Segmente eines Pro-
gramms sowie dessen Einsprungadresse. Sie kann Referenzen auf dynamisch gebundene Biblio-
theken enthalten. Skripte und andere Programme, die einen Interpreter oder eine virtuelle Maschine
voraussetzen, zählen nicht als ausführbare Dateien in diesem Sinne.
Übersetzen (engl.: compiling)
Ein Compiler übersetzt Quelltext einer Programmiersprache in Objektdateien. Beim anschließen-
den Binden entsteht aus Objektdateien und Bibliotheken eine ausführbare Datei.

4 Bibliothek
Objektdatei (engl.: object file)
Eine Objektdatei enthält Code, statische Daten und Konstanten für einen Teil eines Programms
oder einer Bibliothek. Sie kann Referenzen auf Inhalte anderer Objektdateien enthalten.
Bibliothek (engl.: library)
Eine Bibliothek ist eine Sammlung von Objektdateien, die bestimmte Funktionen bereitstellen. Sie
ist entweder für statisches oder für dynamisches Binden ausgelegt. Zur Laufzeit liegt der Inhalt der
Bibliothek in beiden Fällen im Adressraum des Aufrufers.

2021-02-21                                   BS:DaWiK                                             3
Binden (engl.: linking)
Das statische Binden fügt Objektdateien zu einer ausführbaren Datei zusammen. Der Linker löst
alle Referenzen in den Objektdateien auf. Bei Referenzen auf eine statische Bibliothek kopiert
er die relevanten Teile der Bibliothek. Referenzen auf dynamisch gebundene Bibliotheken blei-
ben in der ausführbaren Datei. Der Linker kombiniert Code, statische Daten und Konstanten aller
Objektdateien zu jeweils einem Segment in der ausführbaren Datei.

Dynamisches Binden (engl.: dynamic linking)
Beim Start einer ausführbaren Datei löst der Programmlader die enthaltenen Referenzen auf. Er
lädt jede benötigte, dynamisch gebundene Bibliothek (engl.: shared library) und stellt sie im
Adressraum des Programms bereit. Code und Konstanten einer Bibliothek lädt er für alle Pro-
gramme und Adressräume nur einmal, die statischen Daten pro Adressraum.

Programmierschnittstelle, API (engl.: application programming interface)
Zu jeder Bibliothek gehört ein API. Es beschreibt die von der Bibliothek bereitgestellten Klassen,
Methoden, Funktionen und Datentypen. Das API ist in der Programmiersprache definiert, aus der
die Bibliothek aufgerufen werden soll.

Aufrufschnittstelle, ABI (engl.: application binary interface)
Die Aufrufkonventionen (engl.: calling conventions) eines Compilers legen fest, wie er bei einem
bestimmten Prozessortyp die Parameter und Ergebnisse von Aufrufen in den Registern und auf
dem Stapel übergibt. Aus einer Programmierschnittstelle (API) wird so eine Aufrufschnittstelle
(ABI) für den Prozessortyp. Die Objektdateien eines Programms und seiner Bibliotheken müssen
die gleichen Aufrufkonventionen einhalten. Man kann eine Bibliothek in verschiedenen Program-
miersprachen verwenden, wenn die Aufrufkonventionen der Compiler kompatibel sind.

5 Schichtenmodell
Dicker, fetter Strich
Eine klare Grenze trennt die Infrastruktur eines Betriebssystems von den ablaufenden Instanzen.

Instanzenbereich (engl.: userland, user space)
Jedes gestartete Programm läuft als Instanz in einem eigenen Adressraum, den es sich mit sei-
nen Bibliotheken teilt. Der Prozessor arbeitet hier im Anwendungsmodus. Speicherzugriffe sind
nur auf die Inhalte des Adressraums erlaubt. Für alles, was außerhalb des eigenen Adressraums
passiert, wendet sich eine Instanz an die Infrastruktur.

Infrastruktur (engl.: kernel space)
Die Infrastruktur bzw. der Kern des Betriebssystems lädt beim Booten. Ihre Speicherinhalte liegen
in einem eigenen Kernadressraum. Der Prozessor arbeitet hier im Systemmodus. Die Infrastruktur
kann also die MMU frei konfigurieren. Das erlaubt ihr Zugriffe auf den physischen Speicher sowie
die Adressräume aller Instanzen. Siehe auch „Kern“.

Instanzenschichten
Das Wettstein’sche Schichtenmodell gliedert Instanzen in Steuerung, Anwendungen und Dienste.
Anwendungen sind der Zweck des Systems, unterliegen aber der Steuerung. Dienste unterstützen
beides.

2021-02-21                                  BS:DaWiK                                              4
Systemfunktion
Systemfunktionen stehen allen Instanzen gemeinsam zur Verfügung. Beispiele sind Dateizugrif-
fe, Netzwerk oder eine graphische Benutzerschnittstelle. Der Zugriff auf Funktionen erfolgt meist
über Bibliotheken und deren API. Die Logik einer Funktion kann direkt in einer Bibliothek imple-
mentiert sein, in der Infrastruktur liegen, oder in einer eigenen Instanz (engl.: daemon) ablaufen.
Im letzten Fall nimmt die Bibliothek über die Infrastruktur Kontakt zur Instanz auf. Alle drei Tech-
niken lassen sich in der gleichen Bibliothek kombinieren.

6 Kern
Kern (engl.: kernel)
Der Kern eines Betriebssystems behandelt Unterbrechungen und stellt Funktionen bereit, die ein
Befehlsstrom im Anwendungsmodus nicht ausführen dürfte. Ein Mikrokern (engl.: microkernel)
bietet ein Minimum an Funktionen. Im Extremfall erfüllt er diese nur in Unterbrechungsbehand-
lungen. Gebräuchlicher sind Kerne mit erweiterten Funktionen. Sie verwenden zusätzlich Prozesse
im Adressraum des Kerns, die im Systemmodus ablaufen. Die minimalen Aufgabenbereiche sind:
  1. Bereitstellen von Speicher in Adressräumen
  2. Verteilen von Rechenzeit an Prozesse
  3. Mechanismen zur Interaktion

Kernadressraum (engl.: kernel space)
Ähnlich wie ein Programm besteht der Kern aus Code, Konstanten und statischen Daten. Er ver-
wendet eine Halde, und pro Prozessor einen Stapel für Unterbrechungsbehandlungen. Diese Spei-
cherinhalte liegen in einem speziellen Kernadressraum, der nur im Systemmodus des Prozessors
zugänglich ist. Siehe auch „Adressraum“.

Kernschnittstelle (engl.: kernel ABI)
Der Kern definiert eine Aufrufschnittstelle für Instanzen. Diese übergeben Argumente in Registern
oder auf ihrem Stapel. Der Kernaufruf erfolgt durch eine vom Befehlsstrom der Instanz ausgelöste
Unterbrechung (engl.: software interrupt).

Kernobjekt
Der Kern verwaltet Resourcen wie Adressräume, Prozesse und Sperren, welche über die Kern-
schnittstelle erreichbar sind. Bei einer objektorientierten Sicht auf die Kernschnittstelle sind diese
Resourcen Kernobjekte, mit Attributen und Methoden.

Kernoperation
Ein Kernaufruf kann die gewünschte Operation nicht immer sofort ausführen. Zum Beispiel kann
er eine Sperre nur setzen, wenn sie gerade frei ist. In solchen Fällen speichert der Kern die Daten
des Aufrufs, um die Operation später zu beenden. Bei einer synchronen Operation blockiert er den
aufrufenden Prozess, bis die Operation abgeschlossen ist. Die Unterbrechungsbehandlung beim
Kernaufruf endet trotzdem umgehend. Anschließend erhält ein anderer Prozess den Prozessor.

2021-02-21                                    BS:DaWiK                                              5
7 Speicher
Adressraum (engl.: address space)
Ein Adressraum ist eine logische Sicht auf den Inhalt des Hauptspeichers. Die Größe ist durch
den Prozessor vorgegeben. Rechnet er mit 32–Bit–Adressen, dann umfasst jeder Adressraum 232
Adressen bzw. Byte. Eine Instanz darf in ihrem Adressraum nur auf bestimmte Bereiche zugreifen.
Dazu gehören Code, Konstanten, statische Daten, die Halde und der Stapel. Die Infrastruktur kann
auf Anfrage weitere Bereiche in den Adressraum einblenden. Siehe auch „Segment“.

Übersetzungstabelle (engl.: page table)
Die MMU übersetzt bei Speicherzugriffen die logischen Adressen eines Befehlsstroms in physi-
sche auf dem Systembus. Dazu dient eine Tabelle mit Seiteneinträgen. Die typische Seitengröße
ist 4 KB. Jeder Adressraum verwendet eine andere Übersetzungstabelle. Zugriffe auf eine logische
Adresse ohne Übersetzungseintrag führen zu einem Seitenfehler, also einer Unterbrechung. Die
Infrastruktur ergänzt dann die Tabelle oder bricht den Befehlsstrom ab. Im Übersetzungseintrag
steht auch die Art der erlaubten Zugriffe: Lesen, Schreiben, Ausführen. Zudem setzt die MMU
Indikatoren in den Einträgen. Diese zeigen an, ob ein Lese- oder Schreibzugriff stattfand.

Segment (engl.: memory region)                                            früher: Adressbereich
Ein Segment ist ein Datenspeicher, der in einen Adressraum eingeblendet und damit für Speicher-
zugriffe verfügbar wird. Die Daten eines Segments erscheinen an aufeinanderfolgenden Adressen.
Die Größe eines Segments ist ein Vielfaches der Seitengröße der MMU. Private Segmente erschei-
nen nur in einem Adressraum, zum Beispiel als Halde oder Stapel. Gemeinsame Segmente erschei-
nen in mehreren Adressräumen, zum Beispiel für Code und Konstanten dynamischer Bibliotheken.
Instanzen können schreibbare gemeinsame Segmente (engl.: shared memory) einrichten. Ein ge-
meinsames Segment liegt in verschiedenen Adressräumen an unterschiedlichen Adressen.

Lagetabelle
Der Kern erstellt die Einträge in Übersetzungstabellen. Zu diesem Zweck vermerkt die Lagetabelle
eines Segments, wo dessen Inhalte liegen. Im einfachsten Fall steht dort eine Reihe physischer
Seiten des Hauptspeichers. Inhalte können aber auch auf Massenspeichern liegen und erst bei
Zugriff in den Hauptspeicher geladen werden. Seiten eines neuen Segments sind bis zum ersten
Zugriff leer und liegen nirgendwo.

Virtueller Speicher (engl.: virtual memory)
Die Speicherinhalte eines Adressraums müssen nicht dauerhaft im Hauptspeicher liegen. Seiten
können auf Massenspeichern liegen, um mehr Hauptspeicher für andere Adressräume verfügbar zu
machen. Der Seitenfehler beim Zugriff veranlasst das System, den fehlenden Seiteninhalt nachzu-
laden und die Übersetzungstabelle zu ergänzen, bevor es den Befehlsstrom fortsetzt. Im Gegenzug
sucht es regelmäßig nach Inhalten, die es auslagern kann, um freie Seiten für das Nachladen oder
neue Adressräume vorzuhalten.

Dateieinblendung (engl.: memory–mapped IO)
Eine Datei kann als Segment in einen Adressraum eingeblendet werden, ohne ihren Inhalt sofort
und vollständig zu laden. Die Mechanismen für virtuellen Speicher laden einzelne Seiten erst bei
Zugriff und speichern Veränderungen später wieder ab. Das funktioniert auch mit Teilen von Da-
teien, zum Beispiel für Code und Konstanten dynamischer Bibliotheken.

2021-02-21                                    BS:DaWiK                                        6
8 Rechenzeit
Prozess (engl.: thread, lightweight process)
Jeder Befehlsstrom einer Instanz ist ein Prozess. Eine Instanz erhält Rechenzeit, wenn die Infra-
struktur einen der Prozessoren dafür einsetzt, einen Befehlsstrom der Instanz voranzutreiben. Eine
Instanz kann mehrere Prozesse definieren und dadurch mehrere Prozessoren gleichzeitig nutzen.

Prozesszustand (engl.: process state)
Je nach Betriebssystem gibt es unterschiedliche Modelle, aber die wichtigsten Zustände sind:
     Rechnend: Der Befehlsstrom wird gerade ausgeführt.
        Bereit: Der Befehlsstrom braucht einen Prozessor.
     Blockiert: Der Befehlsstrom wartet auf ein Ereignis, eine Bedingung.
Rechnend benutzt der Befehlsstrom die Rechenumgebung eines Prozessors. Sonst liegen seine
Registerinhalte im RAM. Zu Beginn einer Unterbrechunsbehandlung sichert der Kern die Register-
inhalte des rechnenden Prozesses dort. Dann kann der Kern den Prozess wechseln, umschalten.

Aufgreifer (engl.: scheduler)
Der Aufgreifer ist Teil des Kerns und entscheidet, welche Prozesse rechnen. Er verwaltet eine
Bereitmenge und verschiebt Prozesse zwischen den Zuständen Rechnend und Bereit. Auslöser
dafür sind der Ablauf einer Zeitscheibe oder Kernoperationen, die Prozesszustände ändern. Ein
Kernaufruf kann den aufrufenden, rechnenden Prozess blockieren sowie andere deblockieren. Gibt
es keine Arbeit, führen Prozessoren stromsparende Leerlaufprozesse (engl.: idle processes) aus.

Priorität (engl.: priority)
Der Aufgreifer entscheidet anhand von Prioritäten, welche Prozesse wieviel Rechenzeit erhalten.
Prozesse können in Gruppen zusammengefasst sein, zum Beispiel pro Benutzer, um eine fairere
Verteilung zu gewährleisten. Die Datenstruktur der Bereitmenge hängt eng mit den Prioritäten zu-
sammen. Verbreitet ist die Multilevel Feedback Queue. Sie bevorzugt schnell reagierende Prozesse
gegenüber rechenintensiven.

Wartemenge (engl.: queue)
Blockierte Prozesse warten auf ein Ereignis, eine Bedingung. Jedes Kernobjekt, das blockierende
Operationen anbietet, braucht mindestens eine Wartemenge für die dort blockierten Prozesse. Jeder
blockierte Prozess befindet sich in einer Wartemenge. Wartemengen können Zusatzinformationen
enthalten, zum Beispiel den Empfangspuffer bei Prozessen, die auf eine Nachricht warten. Die
Sortierung in einer Wartemenge hängt von deren Verwendung ab. Reihenfolge des Blockierens
(FIFO, engl.: first in, first out) oder Priorität der Prozesse liegen nahe, andere sind möglich.

Ereignisse
Kernoperationen tragen zu Ereignissen bei und informieren darüber. Ein Beispiel ist die Übertra-
gung einer Nachricht. Typische Kopplungsformen für Sende- und Empfangsoperationen sind:
    Synchron:     Aufrufer trägt bei und blockiert bis zum Ereignis. (Empfänger, auch Sender)
   Asynchron:     Aufrufer trägt bei und arbeitet weiter, ignoriert das Ereignis. (Sender)
  Versuchend:     Aufrufer löst das Ereignis sofort aus, falls gerade möglich. (einer von beiden)
Unterbrechend:    Aufrufer trägt bei und arbeitet weiter, das Ereignis unterbricht ihn. (beide)

2021-02-21                                   BS:DaWiK                                               7
9 Kontakt zur Außenwelt
Geräte, Treiber
Zugriff auf Geräte, und Dialog mit Benutzern an Geräten, erfolgt über Peripheriechips. Treiber in
der Infrastruktur oder in Instanzen steuern die Peripheriechips und Geräte. Anwendungen nutzen
die Dienste der Treiber mittels Interaktionsmechanismen der Infrastruktur.
Interaktion (engl.: IPC, inter–process communication)
Prozesse können nur auf den Adressraum ihrer Instanz direkt zugreifen. Zusammenarbeit zwischen
Instanzen, ebenso wie Sychronisation zwischen Prozessen der gleichen Instanz, erfolgt über die
Infrastruktur. Anwendungsnahe Mechanismen wie Datenströme oder Dateieinblendungen abstra-
hieren von komplexen Vorgängen im System. Systemnahe Mechanismen entsprechen einfachen
Kernobjekten, wie in den folgenden Beispielen.
Semaphor (engl.: semaphore)
Ein Semaphor ist ein Zähler mit Operationen zum Hoch- und Runterzählen. Falls Runterzählen
zu einem negativen Zählerstand führt, blockiert es den aufrufenden Prozess. Hochzählen erlaubt
blockierten Prozessen, fortzusetzen. Das Semaphor dient zur Resourcenverwaltung, als Sperre oder
als Signal. Sein Erfinder, Edsger W. Dijkstra, nannte die Operationen V (hoch) und P (runter).
Sperre (engl.: lock)
Eine Sperre kann verhindern, dass Prozesse auf vorübergehend inkonsistente Daten zugreifen. Vor
Zugriffen wird die Sperre gesetzt, danach wieder freigegeben bzw. gelöscht. Das Setzen der Sperre
blockiert den Aufrufer, falls sie nicht frei ist. Exklusivsperren serialisieren alle Zugriffe auf die je-
weiligen Daten. Leser–Schreiber–Sperren zum Beispiel erlauben auch parallele Zugriffe mehrerer
Leser, solange kein Schreiber die Sperre hält.
Kanal (engl.: channel, port, queue)
Ein Kanal dient zum Senden und Empfangen von Nachrichten, also Datenpaketen. Manche Im-
plementierungen puffern Nachrichten, falls kein Empfänger wartet. Manche Implementierungen
verlangen vorab den Aufbau einer Verbindung. Angepasste Mechanismen ermöglichen die Über-
tragung von Nachrichten per Netzwerk auf andere Rechner.
Signal (engl.: signal)
Ein Signal ist ein Hinweis, dass ein bestimmtes Ereignis stattfand, eine Bedingung eingetreten
ist. Die Bedeutung des Signals muss vorab vereinbart sein. Signale mit Zähler können mehrfach
gegeben und nacheinander abgeholt werden, zum Beispiel an einem Semaphor. Binärsignale lie-
gen vor oder nicht, aber höchstens einfach. Binärsignale werden gerne in Gruppen als Bitmaske
implementiert. So kann ein Prozess mit einem Aufruf auf eines von mehreren Signalen warten.
Datenströme (engl.: streams)
Datenströme sind eine Abstraktion für verschiedene Datenverbindungen. Ein Strom ist eine Folge
von Bytes, die eine Instanz liest oder schreibt. Ströme führen meist nur in eine Richtung und
können enden (EOF, engl.: end of file). Typische Quellen und Senken für Ströme sind:
         Datei:   Lesen oder Schreiben (Umschalten ist problematisch), positionierbar
       Konsole:   Terminalfenster zum Benutzer, ein Strom pro Richtung, Cursorsteuerung
        Socket:   Netzwerkverbindung, ein Strom pro Richtung
          Pipe:   Verbindung zwischen zwei Instanzen, eine schreibt, die andere liest

2021-02-21                                     BS:DaWiK                                                8
Sie können auch lesen