Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Einführung in Betriebssysteme

Hey Habr! Ich möchte Sie auf eine Reihe von Artikeln und Übersetzungen einer meiner Meinung nach interessanten Literatur aufmerksam machen – OSTEP. In diesem Material wird ausführlich auf die Arbeit unixähnlicher Betriebssysteme eingegangen, nämlich auf die Arbeit mit Prozessen, verschiedenen Schedulern, Speicher und anderen ähnlichen Komponenten, aus denen ein modernes Betriebssystem besteht. Das Original aller Materialien können Sie hier sehen hier. Bitte beachten Sie, dass die Übersetzung unprofessionell (ziemlich frei) angefertigt wurde, aber ich hoffe, dass ich die allgemeine Bedeutung beibehalten habe.

Laborarbeiten zu diesem Thema finden Sie hier:
- Original: page.cs.wisc.edu/~remzi/OSTEP/Homework/homework.html
- Original: github.com/remzi-arpacidusseau/ostep-code
- meine persönliche Anpassung: github.com/bykvaadm/OS/tree/master/ostep

Sie können auch auf meinem Kanal vorbeischauen Telegramm =)

Programmbetrieb

Was passiert, wenn ein Programm ausgeführt wird? Ein laufendes Programm macht eine einfache Sache: Es führt Anweisungen aus. Jede Sekunde ruft der Prozessor Millionen und möglicherweise sogar Milliarden von Anweisungen aus dem RAM ab, dekodiert sie wiederum (er erkennt beispielsweise, zu welchem ​​Typ diese Anweisungen gehören) und führt sie aus. Dies kann das Hinzufügen zweier Zahlen, der Zugriff auf den Speicher, das Überprüfen einer Bedingung, das Springen zu einer Funktion usw. sein. Nach der Ausführung einer Anweisung fährt der Prozessor mit der Ausführung einer anderen fort. Und so werden Anweisungen nacheinander ausgeführt, bis das Programm endet.
Dieses Beispiel wird natürlich als vereinfacht betrachtet. Um den Prozessor zu beschleunigen, können Sie mit moderner Hardware tatsächlich Anweisungen außerhalb der Reihe ausführen, mögliche Ergebnisse berechnen, Anweisungen gleichzeitig ausführen und ähnliche Tricks ausführen.

Von Neumann-Rechenmodell

Die von uns beschriebene vereinfachte Arbeitsform ähnelt dem Von-Neumann-Rechenmodell. Von Neumann ist einer der Pioniere der Computersysteme, er ist auch einer der Autoren der Spieltheorie. Während das Programm ausgeführt wird, finden eine Reihe anderer Ereignisse, viele andere Prozesse und Logikarbeiten von Drittanbietern statt, deren Hauptzweck darin besteht, den Start, den Betrieb und die Wartung des Systems zu vereinfachen.
Es gibt eine Reihe von Software, die dafür verantwortlich ist, die Ausführung von Programmen zu vereinfachen (oder sogar die gleichzeitige Ausführung mehrerer Programme zu ermöglichen), die es Programmen ermöglicht, denselben Speicher zu teilen und mit verschiedenen Geräten zu kommunizieren. Eine solche Software (Software) wird im Wesentlichen als Betriebssystem bezeichnet. Zu ihren Aufgaben gehört die Überwachung, ob das System korrekt und effizient funktioniert, sowie die Gewährleistung einer einfachen Verwaltung dieses Systems.

Operationssystem

Ein Betriebssystem, abgekürzt OS, ist eine Reihe miteinander verbundener Programme, die dazu dienen, Computerressourcen zu verwalten und die Benutzerinteraktion mit einem Computer zu organisieren..
Das Betriebssystem erreicht seine Wirksamkeit erst durch die wichtigste Technik – die Technik Virtualisierung. Das Betriebssystem interagiert mit einer physischen Ressource (Prozessor, Speicher, Festplatte usw.) und wandelt sie in eine allgemeinere, leistungsfähigere und benutzerfreundlichere Form seiner selbst um. Daher kann man zum allgemeinen Verständnis das Betriebssystem ganz grob mit einer virtuellen Maschine vergleichen.
Damit Benutzer dem Betriebssystem Befehle erteilen und so die Funktionen der virtuellen Maschine nutzen können (z. B. das Ausführen eines Programms, das Zuweisen von Speicher, den Zugriff auf eine Datei usw.), stellt das Betriebssystem eine sogenannte Schnittstelle bereit API (Application Programming Interface) und an die Sie Anrufe tätigen können (Call). Ein typisches Betriebssystem ermöglicht die Durchführung von Hunderten von Systemaufrufen.
Da die Virtualisierung schließlich die Ausführung mehrerer Programme ermöglicht (wodurch die CPU gemeinsam genutzt wird) und gleichzeitig auf ihre Anweisungen und Daten zugreift (wodurch der Speicher gemeinsam genutzt wird) und auf Festplatten zugreift (wodurch E/A-Geräte gemeinsam genutzt werden), wird das Betriebssystem auch als a bezeichnet Ressourcenmanager. Jeder Prozessor, jede Festplatte und jeder Speicher ist eine Ressource des Systems, und daher besteht eine der Rollen des Betriebssystems darin, diese Ressourcen zu verwalten, und zwar effizient, ehrlich oder umgekehrt, je nachdem, für welche Aufgabe dieses Betriebssystem zuständig ist ist entworfen.

CPU-Virtualisierung

Betrachten Sie das folgende Programm:
(https://www.youtube.com/watch?v=zDwT5fUcki4&feature=youtu.be)

Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Es führt keine besonderen Aktionen aus, sondern ruft lediglich eine Funktion auf spinnen(), dessen Aufgabe darin besteht, die Zeitprüfung zu durchlaufen und nach Ablauf einer Sekunde zurückzukehren. Somit wird die Zeichenfolge, die der Benutzer als Argument übergeben hat, auf unbestimmte Zeit wiederholt.
Lassen Sie uns dieses Programm ausführen und ihm das Zeichen „A“ als Argument übergeben. Das Ergebnis ist nicht besonders interessant – das System führt einfach ein Programm aus, das regelmäßig das Zeichen „A“ anzeigt.
Probieren wir nun die Option aus, wenn viele Instanzen desselben Programms ausgeführt werden, aber zur Verdeutlichung unterschiedliche Buchstaben ausgeben. In diesem Fall wird das Ergebnis etwas anders ausfallen. Obwohl wir einen Prozessor haben, wird das Programm gleichzeitig ausgeführt. Wie passiert es? Es stellt sich jedoch heraus, dass das Betriebssystem nicht ohne die Hilfe von Hardwarefunktionen eine Illusion erzeugt. Die Illusion, dass das System über mehrere virtuelle Prozessoren verfügt, wodurch aus einem einzelnen physischen Prozessor eine theoretisch unendliche Anzahl wird und es dadurch scheinbar möglich ist, dass Programme gleichzeitig ausgeführt werden. Diese Illusion heißt CPU-Virtualisierung.
Dieses Bild wirft viele Fragen auf, wenn zum Beispiel mehrere Programme gleichzeitig laufen wollen, welches wird dann gestartet? Für diese Frage sind die „Richtlinien“ des Betriebssystems verantwortlich. Richtlinien werden an vielen Stellen im Betriebssystem verwendet und beantworten Fragen wie diese. Sie sind die grundlegenden Mechanismen, die das Betriebssystem implementiert. Daher die Rolle des Betriebssystems als Ressourcenmanager.

Speichervirtualisierung

Schauen wir uns nun die Erinnerung an. Das physikalische Speichermodell in modernen Systemen wird als Array von Bytes dargestellt.. Um aus dem Speicher zu lesen, müssen Sie angeben Zelladresseum darauf zuzugreifen. Um Daten zu schreiben oder zu aktualisieren, müssen Sie auch die Daten und die Adresse der Zelle angeben, in die sie geschrieben werden sollen.
Während der Programmausführung wird ständig auf den Speicher zugegriffen. Ein Programm speichert seine gesamte Datenstruktur im Speicher und greift darauf zu, indem es verschiedene Anweisungen ausführt. Die Anweisungen werden mittlerweile auch im Speicher gespeichert, sodass bei jeder Anforderung für die nächste Anweisung auch auf sie zugegriffen wird.

malloc()-Aufruf

Betrachten Sie das folgende Programm, das mithilfe des Aufrufs einen Speicherbereich zuweist malloc () (https://youtu.be/jnlKRnoT1m0):

Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Das Programm macht mehrere Dinge. Zuerst wird etwas Speicher zugewiesen (Zeile 7), dann wird die Adresse der zugewiesenen Zelle ausgegeben (Zeile 9) und Null wird in den ersten Steckplatz des zugewiesenen Speichers geschrieben. Als nächstes tritt das Programm in eine Schleife ein, in der es den im Speicher an der Adresse in der Variablen „p“ gespeicherten Wert erhöht. Es druckt auch die Prozess-ID von sich selbst. Die Prozess-ID ist für jeden laufenden Prozess eindeutig. Nachdem wir mehrere Kopien gestartet haben, werden wir auf ein interessantes Ergebnis stoßen: Wenn Sie im ersten Fall nichts tun und einfach mehrere Kopien ausführen, sind die Adressen unterschiedlich. Aber das fällt nicht unter unsere Theorie! Richtig, da bei modernen Distributionen die Speicher-Randomisierung standardmäßig aktiviert ist. Wenn es deaktiviert ist, erhalten wir das erwartete Ergebnis – die Speicheradressen zweier gleichzeitig laufender Programme stimmen überein.

Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Im Ergebnis stellt sich heraus, dass zwei unabhängige Programme mit eigenen privaten Adressräumen arbeiten, die wiederum vom Betriebssystem im physischen Speicher abgebildet werden. Daher wirkt sich die Verwendung von Speicheradressen innerhalb eines Programms in keiner Weise auf andere aus, und jedes Programm hat den Eindruck, dass es über einen eigenen Teil des physischen Speichers verfügt, der ihm vollständig zur Verfügung steht. Die Realität ist jedoch, dass der physische Speicher eine gemeinsam genutzte Ressource ist, die vom Betriebssystem verwaltet wird.

Konsistenz

Ein weiteres wichtiges Thema innerhalb von Betriebssystemen ist − Konsistenz. Dieser Begriff wird verwendet, wenn es um Probleme im System geht, die auftreten können, wenn mit vielen Dingen gleichzeitig innerhalb desselben Programms gearbeitet wird. Selbst innerhalb des Betriebssystems selbst treten Konsistenzprobleme auf. In den vorherigen Beispielen zur Speicher- und Prozessorvirtualisierung haben wir festgestellt, dass das Betriebssystem viele Dinge gleichzeitig verwaltet – es startet den ersten Prozess, dann den zweiten und so weiter. Wie sich herausstellte, kann dieses Verhalten zu einigen Problemen führen. So treten beispielsweise bei modernen Multithread-Programmen solche Schwierigkeiten auf.

Betrachten Sie das folgende Programm:

Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Das Programm in der Hauptfunktion erstellt mithilfe des Aufrufs zwei Threads pthread_create(). In diesem Beispiel kann man sich einen Thread als eine Funktion vorstellen, die zusammen mit anderen Funktionen im selben Speicherbereich ausgeführt wird, wobei eindeutig mehr als eine Funktion gleichzeitig ausgeführt wird. In diesem Beispiel startet jeder Thread die Funktion und führt sie aus worker(), was wiederum einfach die Variable erhöht,.

Lassen Sie uns dieses Programm mit einem Argument von 1000 ausführen. Wie Sie vielleicht vermutet haben, sollte das Ergebnis 2000 sein, da jeder Thread die Variable 1000-mal erhöht hat. Allerdings ist nicht alles so einfach. Versuchen wir, das Programm mit einer Größenordnung mehr Wiederholungen auszuführen.

Betriebssysteme: Drei einfache Teile. Teil 1: Einführung (Übersetzung)

Wenn wir eine Zahl eingeben, zum Beispiel 100000, erwarten wir als Ausgabe die Zahl 200000. Wenn wir jedoch die Zahl 100000 mehrmals eingeben, sehen wir nicht nur nicht die richtige Antwort, sondern erhalten auch verschiedene falsche Antworten. Die Antwort liegt darin, dass zum Erhöhen der Zahl drei Vorgänge erforderlich sind: Extrahieren der Zahl aus dem Speicher, Erhöhen und anschließendes Zurückschreiben der Zahl. Da nicht alle diese Anweisungen atomar (alle gleichzeitig) ausgeführt werden, können seltsame Dinge wie diese passieren. Dieses Problem wird in der Programmierung aufgerufen Rennbedingung. Wenn unbekannte Kräfte zu einem unbekannten Zeitpunkt die Leistung Ihrer Operationen beeinträchtigen können.

Source: habr.com

Kommentar hinzufügen