IN8014 - Lehrstuhl für Angewandte Informatik
Transcription
IN8014 - Lehrstuhl für Angewandte Informatik
Eingebettete vernetzte Systeme (IN8014) Teil I: Betriebssysteme und Systemsoftware Johann Schlichter Institut für Informatik TU München, Munich, Germany September 2012 Vorlesungsunterlagen (Student Script1 ) 1 Script generated by Targeteam; Not for general Distribution Inhaltsverzeichnis 1 Übersicht 2 1.1 Ziele dieses Vorlesungsteils . . . . . . . . . . . . . . . . . . . . . 2 1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2.1 Anforderungen an Rechensysteme . . . . . . . . . . . . . 3 1.2.2 Struktur eines Rechensystems . . . . . . . . . . . . . . . 5 Literaturübersicht . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3.1 Begleitend zur Vorlesung . . . . . . . . . . . . . . . . . . 6 1.3.2 Weiterführende Literatur . . . . . . . . . . . . . . . . . . 6 1.3 2 Einführung 7 2.1 Betriebssystem - Überblick . . . . . . . . . . . . . . . . . . . . . 7 2.1.1 BS-Hauptaufgaben . . . . . . . . . . . . . . . . . . . . . 7 2.1.2 Systemprogrammierung . . . . . . . . . . . . . . . . . . 10 2.1.3 Hardwarekomponenten . . . . . . . . . . . . . . . . . . . 11 2.1.4 Betriebsarten . . . . . . . . . . . . . . . . . . . . . . . . 11 Betriebssystem-Architektur . . . . . . . . . . . . . . . . . . . . . 13 2.2.1 Monolithischer Ansatz . . . . . . . . . . . . . . . . . . . 13 2.2.2 Mikrokern-Ansatz . . . . . . . . . . . . . . . . . . . . . 15 2.2.3 Beispiel: BS-Architekturen . . . . . . . . . . . . . . . . . 16 2.2.4 Systemaufrufe . . . . . . . . . . . . . . . . . . . . . . . 18 2.2.5 Virtuelle Maschine . . . . . . . . . . . . . . . . . . . . . 19 2.2 3 Synchronisation und Verklemmungen 21 3.1 Thread-Konzept . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.1 22 Charakterisierung von Threads . . . . . . . . . . . . . . . i Schlichter, TU München 3.2 3.3 4 INHALTSVERZEICHNIS Synchronisation . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2.1 Beispiel: gemeinsame Daten . . . . . . . . . . . . . . . . 24 3.2.2 Synchronisierungskonzepte . . . . . . . . . . . . . . . . 26 3.2.3 Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.2.4 Synchronisierung von Java Threads . . . . . . . . . . . . 34 Verklemmungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.3.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . 36 3.3.2 Belegungs-Anforderungsgraph . . . . . . . . . . . . . . . 36 3.3.3 Verklemmungs-Ignorierung . . . . . . . . . . . . . . . . 37 3.3.4 Verklemmungs-Erkennung . . . . . . . . . . . . . . . . . 37 3.3.5 Verklemmungs-Verhinderung . . . . . . . . . . . . . . . 38 3.3.6 Verklemmungs-Vermeidung . . . . . . . . . . . . . . . . 38 3.3.7 Vergleich der Ansätze . . . . . . . . . . . . . . . . . . . 41 Prozess- und Prozessorverwaltung 42 4.1 Fragestellungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 4.2 Prozessverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . 42 4.2.1 Prozesskonzept . . . . . . . . . . . . . . . . . . . . . . . 43 4.2.2 Dispatcher . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.3 Arbeitsmodi . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.4 Systemaufrufe . . . . . . . . . . . . . . . . . . . . . . . 50 4.2.5 Realisierung von Threads . . . . . . . . . . . . . . . . . 51 Prozessorverwaltung . . . . . . . . . . . . . . . . . . . . . . . . 52 4.3.1 Kriterien . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.3.2 Scheduling-Strategien . . . . . . . . . . . . . . . . . . . 54 4.3.3 Thread Scheduling . . . . . . . . . . . . . . . . . . . . . 58 4.3.4 Mehrschichtiges Scheduling . . . . . . . . . . . . . . . . 58 4.3.5 Echtzeit Scheduling . . . . . . . . . . . . . . . . . . . . 60 Unterbrechungskonzept . . . . . . . . . . . . . . . . . . . . . . . 61 4.4.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 61 4.4.2 Unterbrechungsarten . . . . . . . . . . . . . . . . . . . . 61 4.4.3 Behandlung externer Unterbrechungen . . . . . . . . . . 63 4.4.4 Konflikte . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.3 4.4 ii Schlichter, TU München 5 Speicherverwaltung 67 5.1 Fragestellungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5.2 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5.2.1 Adressräume . . . . . . . . . . . . . . . . . . . . . . . . 68 5.2.2 Organisation von Adressräumen . . . . . . . . . . . . . . 68 5.2.3 Fragmentierung . . . . . . . . . . . . . . . . . . . . . . . 70 5.2.4 Forderungen an Adressraumrealisierung . . . . . . . . . . 72 Speicherabbildungen . . . . . . . . . . . . . . . . . . . . . . . . 72 5.3.1 Direkte Adressierung . . . . . . . . . . . . . . . . . . . . 72 5.3.2 Basisadressierung . . . . . . . . . . . . . . . . . . . . . . 74 5.3.3 Seitenadressierung . . . . . . . . . . . . . . . . . . . . . 75 5.3 6 Prozesskommunikation 78 6.1 Fragestellungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 6.2 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 6.2.1 Kommunikationsarten . . . . . . . . . . . . . . . . . . . 78 Nachrichtenbasierte Kommunikation . . . . . . . . . . . . . . . . 82 6.3.1 Elementare Kommunikationsmodelle . . . . . . . . . . . 82 6.3.2 Erzeuger-Verbraucher Problem . . . . . . . . . . . . . . . 86 6.3.3 Modellierung durch ein Petrinetz . . . . . . . . . . . . . . 87 6.3.4 Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 6.3.5 Kanäle . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 6.3.6 Ströme . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 6.4 Client-Server-Modell . . . . . . . . . . . . . . . . . . . . . . . . 90 6.5 Netzwerkprogrammierung . . . . . . . . . . . . . . . . . . . . . 92 6.5.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . 93 6.5.2 Server Protokoll . . . . . . . . . . . . . . . . . . . . . . 94 6.5.3 Client Protokoll . . . . . . . . . . . . . . . . . . . . . . . 95 6.5.4 Bidirektionale Stromverbindung . . . . . . . . . . . . . . 95 6.5.5 Java Socket Class . . . . . . . . . . . . . . . . . . . . . . 96 6.3 7 INHALTSVERZEICHNIS Zusammenfassung 99 iii Schlichter, TU München INHALTSVERZEICHNIS • Prof. J. Schlichter – Lehrstuhl für Angewandte Informatik / Kooperative Systeme, Fakultät für Informatik, TU München – Boltzmannstr. 3, 85748 Garching Email: [email protected] (URL: mailto:[email protected]) Tel.: 089-289 18654 URL: http://www11.informatik.tu-muenchen.de/ 1 Kapitel 1 Übersicht 1.1 Ziele dieses Vorlesungsteils Diese Vorlesung beschäftigt sich mit den technischen Aspekten von Rechensystemen und der Informationsverarbeitung, nämlich der systemnahen Programmierung. Dabei werden in diesem Teil der Vorlesung vor allem Aspekte allgemeiner Betriebssysteme und Prozesskommunikation betrachtet. Der 2. Teil der Vorlesung behandelt dann die Echtzeitaspekte. • Zunächst werden informell die Aufgaben und Eigenschaften eines Betriebssystem dargestellt. Daraus lassen sich die für die Vorlesung relevanten Begriffe ableiten. Weiterhin wird kurz auf Hardware-nahe Programme eingegangen. • Im nächsten Teil der Vorlesung erfolgt der Übergang von sequentiellen zu parallelen Systemen. Zu den Themen, die behandelt hier werden, gehören die Grundlagenprobleme paralleler Systeme und die Verfahren, mit denen diese gelöst werden können: Synchronisation, Verklemmungen. • Im Anschluss daran werden Konzepte und Verfahren von Betriebssystemen, die der wesentliche Teil der Konkretisierung paralleler Systeme sind, behandelt. Insbesondere geht es um die Arbeitsspeicherverwaltung (Arbeitsspeicherverwaltung, "main memory management"), die Prozessverwaltung und die Prozessorzuteilung sowie Mechanismen zur Kontrolle der Nebenläufigkeit. • Prozesse existieren nicht in Isolation, sondern die Kommunikation zwischen den Prozessen ist von zentraler Bedeutung für Lösung vieler Problemstellungen. Der Austausch von Information zwischen Prozessen kann entweder speicherbasiert oder über Nachrichten erfolgen. Die nachrichtenbasierte Prozesskom2 Schlichter, TU München 1.2. MOTIVATION munikation ist gerade für verteilte Rechensysteme, wo Prozesse über ein (lokales oder globales) Rechnernetz miteinander kommunizieren, von großer Bedeutung. Wichtige Aspekte sind hierbei das Client-Server Modell und die Netzwerkprogrammierung. 1.2 Motivation Aufgabe der Informatik ist es, Rechensysteme zu entwickeln und diese Anwendern als leistungsfähige Hilfsmittel für Lösungen ihrer Informationsverarbeitungsprobleme zur Verfügung zu stellen. 1.2.1 Anforderungen an Rechensysteme Rechensysteme sind offene, dynamische, technische Systeme mit Fähigkeiten zur Speicherung und zur Verarbeitung von Information, die für Anwendungen und Anwender nutzbar zur Verfügung gestellt werden sollen. Offenes System Ein Rechensystem R ist ein offenes System sagt zweierlei aus: • R ist als System eine durch Zusammenfassung gebildete, abgegrenzte Einheit, wo zwischen innen (R) und außen (U(R)) unterschieden wird. • R hat eine (offene) Schnittstelle, mit der Einwirkungen von U(R) auf R und Einwirkungen von R auf U(R) möglich sind. • Schnittstelle eines Rechensystems 3 Schlichter, TU München 1.2. MOTIVATION Umgebung U(R) Schnittstelle R - U(R) Rechensystem R Dynamisches System Eigenschaften des Rechensystems R ändern sich mit der Zeit ⇒ Beschreibung des Verhaltens von R. Technisches System Das Rechensystem ist mit hardware- und softwaretechnischen Mitteln realisiert. Informationsspeicherung und -verarbeitung 4 Schlichter, TU München 1.2. MOTIVATION Wissen Information Information Repräsentation Interpretation Daten Daten Nachricht 1.2.2 Struktur eines Rechensystems Datenbank Shell World Wide Web Übersetzer Email Anwendungsprogramme Dateisystem Systemprogramme Betriebssystem Maschinensprache Mikroprogramme / festverdrahtete Programme Hardware physische Komponenten und Geräte • Darstellung von Programmen in maschinennaher Form für bestimmte Anwen5 Schlichter, TU München 1.3. LITERATURÜBERSICHT dungen auch heute noch unerläßlich, beispielsweise für den Übersetzerbau, eingebettete Systeme oder für systemnahe Programmierung in Teilen des Betriebssystems. • Thema der Vorlesung ist systemnahe Programmentwicklung; nebenläufige ("concurrent") Ausführung von mehreren Teilabläufen ⇒ Nichtdeterminismus. 1.3 Literaturübersicht Literatur, die als Basis für diesen Vorlesungsteil verwendet wird. 1.3.1 Begleitend zur Vorlesung • Andrew S. Tanenbaum, "Modern Operating Systems", Prentice Hall, 2008; dazu gibt es eine deutsche Übersetzung Andrew S. Tanenbaum, "Moderne Betriebssysteme", Pearson Studium, 2009 • Abraham Silberschatz, Peter Galvin, Greg Gagne, " Operating System Concepts. Operating System Concepts", Wiley & Sons, 2009 1.3.2 Weiterführende Literatur • Albrecht Achilles, "Betriebssysteme - Eine kompakte Einführung mit Linux", Springer, 2006 • Eduard Glatz, "Betriebssysteme - Grundlagen, Konzepte, Systemprogrammierung", dpunkt.verlag, 2010 • William Stallings, "Operating Systems - Internals and Design Principals", Pearson International Edition, 2011 • George Coulouris, Jean Dollimore, Tim Kindberg, "Distributed Systems Concepts and Design", Addison-Wesley, 2012 • Andrew S. Tanenbaum, Marten van Steen, "Verteilte Systeme - Grundlagen und Paradigmen", Pearson Studium, 2007 6 Kapitel 2 Einführung Definition eines Betriebssystems nach DIN 44300: Das Betriebssystem wird gebildet durch die Programme eines digitalen Rechensystems, die zusammen mit den Eigenschaften der Rechenanlage die Grundlage der möglichen Betriebsarten des digitalen Rechensystems bilden und insbesondere die Ausführung von Programmen steuern und überwachen. 2.1 Betriebssystem - Überblick Ein Betriebssystem realisiert die Schnittstelle zwischen dem Benutzer und der physischen Rechenanlage. Aus der Sicht des Benutzers entsteht durch ein Betriebssystem eine virtuelle Maschine. Für einen Benutzer ist es nicht wichtig, ob in einem Rechensystem Systemfunktionen durch Hardware oder Software realisiert sind. Ein Betriebssystem realisiert insbesondere eine Benutzerschnittstelle. Der Entwurf und die Implementierung von Betriebssystemen gehören zu den klassischen Aufgabenstellungen der Systemprogrammierung. Je nach Art der Hardware gibt es sehr unterschiedliche Typen von Betriebssystemen. Sie reichen von Betriebssystemen für Großrechner, über Server-BS bis hin zu PC-Betriebsystemen und eingebetteten Betriebssystemen (z.B. in einem Android Smartphone). 2.1.1 BS-Hauptaufgaben Ein Betriebssystem (engl. operating system) erfüllt folgende Hauptaufgaben: • Veredeln der Hardware (Virtualisierung). • Steuerung und Kontrolle der Programmausführung. 7 Schlichter, TU München 2.1. BETRIEBSSYSTEM - ÜBERBLICK • Interprozesskommunikation. • Verwaltung der Ressourcen (Speicher, CPU, Platten, Netz etc.) ⇒ Betriebssystem kann als Ressourcenverwalter gesehen werden. – Ressourcenklassen Ein Rechensystem kann als strukturierte Sammlung von Ressourcenklassen betrachtet werden, wobei jede Klasse durch Dienste des Betriebsystems kontrolliert wird. Zentral Ressourcen Aktive Ressourcen Prozessoren (CPUs) Passive Ressourcen Arbeitsspeicher Periphere Ressourcen Kommunikationseinheiten wie Endgeräte ( Tastatur, Drucker, Monitor, Maus) und Netzwerk (lokal, entfernt) Speichereinheiten wie Festplatten, CD, DVD • Anbieten von Diensten in Form von Schnittstellen, so dass die Ressourcen genutzt werden können ⇒ Hardwareunabhängige Programmierschnittstelle, z.B. geräteunabhängige Ein-/Ausgabefunktionen. • Sicherheitsmechanismen. • Arbeitsmodi des Betriebssystems Operationen des Betriebssystems und der Hardware müssen vor Programmierfehlern in Anwendungsprogrammen geschützt werden ⇒ Einführung eines Privilegiensystems. Benutzermodus (user mode): Ausführung von Benutzerprogrammen, kein direkter Hardware-Zugriff, keine privilegierten Befehl, nur virtuelle Adressen. Systemmodus (kernel mode): Ausführungsmodus der Dienste des BSKerns, privilegierte Befehle erlaubt. Benutzermodus begrenzte Auswahl von Maschinenbefehlen Hardwarezugriff nur über BS kein bzw. nur lesender Zugriff auf Systemcode oder Daten 8 Systemmodus alle ausführbaren Maschinenbefehle Vollzugriff auf Hardware exklusiver Zugriff auf Systemcode und Daten Schlichter, TU München 2.1. BETRIEBSSYSTEM - ÜBERBLICK Benutzerprozess Ausführung Benutzerprozess System Aufruf Rückkehr von System Aufruf Benutzermodus Betriebssystemkern Ausführung Systemdienst Systemmodus • Struktureller Aufbau berechtigte Benutzer berechtigte Benutzer Schnittstelle zur Systemumgebung SystemProzesse BenutzerProzesse Betriebssystem-Schnittstelle Prozess verwaltung Speicher verwaltung Datei system Scheduler & Dispatcher EASystem UnterbrechungsSystem Hardware Konfiguration • Ein anderer Blickwinkel 9 zu überprüf. Benutzer login Z u g a n g s k o n t r o l l e Schlichter, TU München 2.1. BETRIEBSSYSTEM - ÜBERBLICK NY Times, Sept, 3, 1997: A decade ago, an "operating system" was just the basic piece of software that ruled the machine and allowed it to manipulate files, converse with any peripherals, and start up programs. That was when a computer was just a nerd toy, not the foundation for the most vital part of of our economy. But today, an "operating system" is much more a vote over who gets to be the richest men in the world. Windows means Microsoft, Java means Sun, while MacOs means That Steve Jobs won’t go broke saving Apple. Linux means no one gets rich because the OS is free, thanks to the help of many volunteers. 2.1.2 Systemprogrammierung Die Programmierung eines Betriebssystems gehört zu dem Bereich der Systemprogrammierung. • Definition Die Systemprogrammierung befasst sich mit der Darstellung, der Realisierung, den Eigenschaften und der Konstruktion derjenigen Algorithmen für ein Rechensystem, die die Bearbeitung und Ausführung von Benutzerprogrammen unter vorgegebenen Qualitätsgesichtspunkten organisieren, d.h. steuern und kontrollieren, und zum Teil selbst durchführen. direkte Nutzung der generischen Systemprogrammierschnittstelle des BS. meist in Programmiersprache C. • Qualitätskriterien können z.B. sein: – Zuverlässigkeit der durchgeführten Berechnung (Behandlung von Systemcrashs, Netzausfällen, fehlerhafter Nachrichtenübermittlung etc.). – Effizienz und Performanz einerseits systemglobal, d.h. es wird versucht, das System optimal auszulasten, andererseits Auftrags-lokal, z.B. es wird versucht, zu garantieren, dass eine Auftragsbearbeitung eine festgelegte Zeitdauer nicht überschreitet. – Einhaltung von Realzeitanforderungen: zeitkritische Aufträge besitzen z.B. eine Deadline bis zu der sie ausgeführt sein müssen. – Durchsetzung von Sicherheitsanforderungen: Schutz der Daten und Informationen vor unberechtigten Zugriffen und Einsichtnahme. – Benutzerfreundlichkeit: bequeme Formulierungsmöglichkeit von Benutzeraufträgen. 10 Schlichter, TU München 2.1.3 2.1. BETRIEBSSYSTEM - ÜBERBLICK Hardwarekomponenten Das Betriebssystem ist sehr eng mit der Hardware des Rechensystems verknüpft, auf dem es ausgeführt wird. Es erweitert den Befehlssatz des Rechners und verwaltet seine Ressourcen. Deshalb an dieser Stelle einen kurzen Überblick über den Aufbau eines Rechensystems. Systembus CPU Speicherbus Northbridge Arbeitsspeicher (Maus, Tastatur) USB AGP EA-Karte Grafik EA-Karte Sound PCI Bus IDE Festplatte Southbridge ISA Bus EA-Karte LAN Drucker PCI = Peripheral Component Interconnect ISA = Industry Standard Architecture USB = Universal Serial Bus AGP = Accelerated Graphics Port (Anschluss von schnellen Grafikkarten). 2.1.4 Betriebsarten Beim Betrieb von Rechenanlagen können bzgl. des Zusammenwirkens von Benutzer und Rechensystem die Betriebsweisen Stapelverarbeitung, Dialogbetrieb, Transaktionsbetrieb und Echtzeitbetrieb unterschieden werden. 11 Schlichter, TU München 2.1. BETRIEBSSYSTEM - ÜBERBLICK • Stapelbetrieb Das Rechensystem verarbeitet Ströme von Auftragspaketen (engl. batch processing). Ein Benutzer deklariert vollständig alle Teile eines Auftragspaketes, bevor es in das System eingegeben wird. Anschließend wird das Auftragspaket durch das Rechensystem abgearbeitet, ohne dass der Benutzer noch Einflussmöglichkeiten hat. Bei Auftreten eines Fehlers muss i.a. nach der Korrektur das gesamte Auftragspaket nochmals gestartet werden. Auftragspakete können in Unterabschnitte zerfallen, z.B. Teilprogrammabläufe. Diese Betriebsart war in den Anfängen von Rechenanlage sehr verbreitet (Nutzung von Lochkarten und Lochstreifen). • Dialogbetrieb Im Dialogbetrieb (engl. Timesharing) erteilt der Benutzer dem Betriebssystem einen Auftrag nach dem anderen im Dialog. Innerhalb eines Benutzerauftrags findet eine Interaktion zwischen dem Benutzer und der Systemumgebung statt (z.B. Eingabe weiterer Daten, Ausgabe von Zwischenergebnissen). Der Dialogbetrieb erfordert eine besondere Gestaltung der Benutzerschnittstelle. Oft wird Betriebssystem und Benutzerschnittstelle (engl. user interface) in einem Atemzug genannt und auch oft gleichgesetzt. Beide sind jedoch getrennt voneinander zusehen. Beispielsweise existierten mit dem X11-Windowsystem und Sun Windowsystem (auf der Basis von Postscript) zwei unterschiedliche Benutzerschnittstellen auf demselben Betriebssystem. • Transaktionsbetrieb Bewältigung einer Vielzahl von kleinen Aufgaben in kürzester Zeit, z.B. Banküberweisungen oder Buchungen. Dabei muss die Bearbeitung folgende Kriterien, wie sie auch von Datenbanken bekannt sind, erfüllen: Atomarität, Konsistenz, Isolation, Dauerhaftigkeit (engl. ACID), d.h. die Bearbeitung muss entweder vollständig ablaufen oder keinerlei Änderung verursachen (Allesoder-nichts Prinzip). • Echtzeitbetrieb In der Prozesssteuerung (automatische Fertigungssysteme, Roboter) und im Multimediabereich sind die Reaktionszeiten des Betriebssystems von großer Bedeutung. Dies erfordert spezielle Mechanismen bei der Behandlung von Ereignissen und Unterbrechungen sowie der CPU-Zuteilung an rechenbereite Prozesse / Threads. Beispielsweise ein Videoserver (bei Nutzung des Streaming Ansatzes) benötigt ein Betriebssystem, das gewisse Echtzeitfähigkeiten hat. Videos müssen mit einer bestimmten Geschwindigkeit abgespielt werden. Die Bilder dürfen an das Abspielprogramm nicht zu langsam (ansonsten ruckelt 12 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR das Videobild) und nicht zu schnell ausgeliefert werden (sonst gehen bei Pufferüberlauf Videobilder verloren). Unterscheidung zwischen harte Echtzeitsysteme: Reaktionszeit darf nicht überschritten werden. weiche Echtzeitsysteme: gewisse Toleranzen bzgl. der Abweichung sind erlaubt. 2.2 Betriebssystem-Architektur In der Praxis findet man einige verschiedene BS-Architekturkonzepte, wobei der monolithische Ansatz und zunehmend auch der Mikrokern-Ansatz am weitesten verbreitet sind. 2.2.1 Monolithischer Ansatz Das Betriebssystem besteht aus einer umfangreichen Menge an Funktionen, die sich bei Bedarf gegenseitig aufrufen können. Die Funktionen werden in einem großen BS-Kern zusammengefasst. Der BS-Kern wird durch Aufruf von Systemdiensten betreten. BS-Kern arbeitet im Systemmodus. Er hat hohe Ablaufpriorität. Er ist permanent im Arbeitsspeicher. 13 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Anwendung Benutzerprozess Anwendung Benutzerprozess Benutzer-Modus (User Mode) System-Modus (Kernel Mode) Systemdienste (Hauptprozedur) Hilfs funktionen Hardware • komplexe, monolithische Betriebssystem sind sehr schwierig zu warten und zu erweitern. • Geschichtete Systeme Einen Ausweg aus der Problematik monolithischer Systeme bieten geschichtete Systeme; das Betriebssystem besteht aus einer Hierarchie abstrakter Maschinen. Jede Schicht hat wohldefinierte Schnittstellen und eine wohldefinierte Aufgabe ⇒ Reduktion der Systemkomplexität. 14 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Anwendungen Funktionsschnittstelle Schicht N abstrakte Maschine N Funktionsschnittstelle Schicht N-1 abstrakte Maschine N - 1 Funktionsschnittstelle Schicht 0 abstrakte Maschine 0 Rechnerhardware 2.2.2 Mikrokern-Ansatz Der Trend moderner Betriebssystem geht hin zu einem Mikrokern-Ansatz. Im Mikrokern sind nur mehr Basismechanismen, z.B. Prozesskommunikation (Austausch von Nachrichten), CPU-Zuteilung. Möglichst viele Subsysteme sind als Systemprozesse außerhalb des Mikrokerns realisiert. Sie laufen im Benutzermodus ab, z.B. Dateisystem, Verwaltungsstrategien, Speicherverwaltung. Man spricht im Zusammenhang mit diesem Ansatz auch von einer Client/ServerStruktur. Systemfunktionen werden als Serverprozesse im Benutzermodus ausgeführt. Benötigt ein Prozess (Client) eine Dienstleistung schickt er eine Anforderung an einen anderen Prozess (Server), der die Dienstleistung erfüllt und die Antwort an den Client zurückgibt. Die Kommunikation zwischen den beteiligten Prozessen erfolgt über den Mikrokern. Durch die Ausgliederung in Serverprozesse ist eine Trennung von Mechanismus und Strategie möglich. Die Strategien werden in Serverprozessen im Benutzermodus realisiert, während der Mikrokern wenige Basismechanismen umfasst. 15 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Einfaches Austauschen von Subsysteme ⇒ ermöglicht die einfache Anpassung von Systemanforderungen. Benutzer Programm Memory Server Prozess Server Netzwerk Server File Server Display Server Benutzer-Modus (User Mode) System-Modus (Kernel Mode) Anforderung Mikrokern Antwort Hardware 2.2.3 Beispiel: BS-Architekturen Unix Betriebssystem Die nachfolgende Abbildung skizziert die wesentlichen Komponenten des Unix Betriebssystems. Der Unix-BS-Kern enthält die Datei-, Prozess- und Prozessorverwaltung, die Speicherverwaltung und die Geräte-Treiber. Programme Bibliotheken (z.B. lib.a) Shells Systemschnittstelle u.a. open,close, read, write; fork, exec, kill, ... Datei System Geräte Treiber Prozess verwaltung Prozessor verwaltung Unterbrechungs behandlung Arbeitsspeicher verwaltung Hardware 16 Benutzungsschnittstelle Programmierschnittstelle Betriebssystemkern Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Windows NT Betriebssystem Mit Hilfe von HAL wird versucht, die meisten Maschinenabhängigkeiten zu verbergen. HAL präsentiert dem restlichen BS abstrakte Hardwaregeräte (z.B. Systembus, Arbeitsspeicher etc). Logon Process OS/2 Client Win32 Client OS/2 Subsystem Security Subsystem Posix Client Applications Posix Subsystem Protected Subsysteme (Servers) Win32 Subsystem Systemaufrufe System Interface (DLL) User Mode Kernel Mode System Services Object Manager Security Manager Process Manager Local Procedure Call Facility Virtual Memory Manager I/O Manager File Systems Cache Mgr NT Executive Device Drivers Network Drivers Kernel Hardware Abstraction Layer (HAL) Hardware Manipulation Hardware Linux Betriebssystem Linux begann Anfang der 1990er Jahre als eine Unix Variante für den IBM PC; erste Version durch Linus Torvalds (1991). Linux ist frei und Quellcode ist verfügbar. kollaborative Weiterentwicklung durch Open Source Community. • kein Mikrokern-Ansatz, jedoch modulare Struktur. dynamic linking. Module sind hierarchisch organisiert. • jeder Modul ist durch 2 Datenstrukturen beschrieben. 17 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Modulbeschreibung, u.a Modulname, Größe, Zahl der exportierten Symbole und referenzierte Module. Symbol-Tabelle. user mode Prozesse System calls Signals Processes & scheduler Virtual memory 2.2.4 device driver (Char) Traps faults Physical memory CPU Main memory kernel mode File system Network protocols Device driver (Block) Network driver Interrupt terminal disk Network interface controller Systemaufrufe Die Schnittstelle zwischen dem Betriebssystem und den Benutzerprogrammen wird durch eine Menge von Systemaufrufen (engl. system calls) gebildet. Sie stellen für Benutzerprogramme die einzige Schicht zum Zugriff auf Dienste des Betriebssystems and damit zur Nutzung der Hardware dar. • in Benutzerprogrammen werden Systemaufrufe nicht direkt verwendet, sondern dies erfolgt über die Einbindung von Systembibliotheken, z.B. C-Library. 18 Schlichter, TU München 2.2. BETRIEBSSYSTEM-ARCHITEKTUR main ( ) { -------------printf ("hello“); -------------- Anwendung } Benutzermodus ------------printf erledigt Formatierung -------------Systemaufruf Systemmodus ------------write (1, "hello“, 5); -------------- Bibliotheksfunktion Betriebssystemkern Hardware Z.B. Zugriff auf Festplatte • Systemaufruf führt zum Übergang vom Benutzermodus in den Systemmodus. • Beispiele von Systemaufrufen Prozessmanagement: fork, waitpid, exit. Dateimanagement: open, close, read, write. Verzeichnismanagement: mkdir, rmdir, link, mount. Gerätemanagement: request/release device, get/set device attributes. Kommunikationsmanagement: connection. 2.2.5 send/receive messages, create/delete Virtuelle Maschine Virtualisierungskonzept erlaubt die gleichzeitige Bereitstellung mehrerer Betriebssysteme auf einem Rechner. Isolierung der virtuellen Maschinen. gemeinsame Nutzung von Dateien möglich. Beispiel VMware (URL: http://www.vmware.com/). 19 Schlichter, TU München Applikation 2.2. BETRIEBSSYSTEM-ARCHITEKTUR Applikation Applikation Gast-Betriebssystem (free BSD) Gast-Betriebssystem (Windows XP) virtuelle CPU virtueller Speicher virtuelle Geräte virtuelle CPU virtueller Speicher virtuelle Geräte Virtualisierungsschicht Host Betriebssystem (Linux) Hardware CPU Arbeitsspeicher E/A-Geräte Die Java Virtual Machine (JVM) spezifiziert einen abstrakten Computer, auf dem Java Programme ausgeführt werden. JVM ist ein Softwaresystem, das auf dem Host-Betriebssystem ausgeführt wird. 20 Kapitel 3 Synchronisation und Verklemmungen Historisch gesehen war der Ausgangspunkt eine Ein-Benutzer, Ein-Programm Rechenanlage und zwar ohne ein Betriebssystem, das die Ausführung von Programmen koordiniert. Für die Ausführung von mehreren Programmen, insbesondere wenn sie parallel ausgeführt werden sollen, sind eine Reihe von organisatorischen Maßnahmen notwendig. Die angesprochenen organisatorischen Aufgaben sind wesentlicher Bestandteil der Aufgaben eines Betriebssystems und die Programmierung eines Betriebssystems gehört zu dem Bereich der systemnahen Programmierung. Typischerweise finden in einem allgemeinen Rechensystem eine Vielzahl paralleler Abläufe statt, die miteinander koordiniert werden müssen. 3.1 Thread-Konzept Threads sind ein BS-Konzept für die Realisierung von nebenläufigen Aktionen in einem Rechensystem. Threads (Kontrollflüsse) beschreiben die Aktivitäten in einem Rechensystem. Sie können als virtuelle Prozessoren aufgefasst werden, die jeweils für die Ausführung eines zugeordneten Programms in einem Adressraum verantwortlich sind. Threads konkurrieren um die physische CPU, um ablaufen zu können. In traditionellen Umgebungen hat jeder Prozess genau einen Thread, der den Kontrollfluss des Prozess repräsentiert, während in MultithreadedUmgebungen ein Prozess mehrere Threads besitzen kann. 21 Schlichter, TU München 3.1. THREAD-KONZEPT Prozess Benutzer Adressraum Thread Thread Betriebssystem 3.1.1 Charakterisierung von Threads Aus BS-Sicht ist ein Prozess definiert durch einen Adressraum. eine darin gespeicherte Handlungsvorschrift in Form eines sequentiellen Programms (Programmcode). einen oder mehreren Aktivitätsträgern, die dynamisch die Handlungsvorschrift ausführen ⇒ Threads. Motivation Ein Thread ist die Abstraktion eines physischen Prozessors; er ist ein Träger einer sequentiellen Aktivität. Gründe für die Einführung von Threads: • mehrere Threads ermöglichen Parallelität innerhalb eines Prozesses unter Nutzung des gemeinsamen Adressraums. • Aufwand für Erzeugen und Löschen von Threads ist geringer als für Prozesse. Threads führen nicht so einen großen Ballast an Information mit sich als Prozesse. Beispielsweise muss bei der Erzeugung eines Prozesses durch das BS ein neuer Adressraum generiert werden; Threads laufen im bereits vorhandenen Adressraum ab. Deshalb spricht man bei Threads auch von Leichtgewichtsprozesse ("light weight processes"), da sie erheblich weniger Verwaltungsinformation als normale Prozesse ("heavy weight processes") benötigen. • Verbesserung der Performanz der Applikationsausführung durch Nutzung mehrerer Threads. Dieses Argument ist besonders dann von Bedeutung, wenn 22 Schlichter, TU München 3.1. THREAD-KONZEPT die Applikation (und damit der zugehörige Prozess) sowohl CPU- als auch E/Aintensive Aktivitäten beinhaltet. E/A-Wartezeiten innerhalb einer Applikation können durch andere rechenbereite Threads der Applikation genutzt werden. Dagegen gewinnen CPU-dominierte Applikationen durch die Parallelisierung mittels Threads weniger an Performanz (falls nur eine CPU zur Verfügung steht). • Threads ermöglichen bei einem Multiprozessor-Rechensystem echte Parallelität innerhalb einer Applikation. Prozess vs. Thread Prozesse und Threads haben unterschiedliche Zielsetzungen: Prozesse gruppieren Ressourcen, Threads sind Aktivitätsträger, die zur Ausführung einer CPU zugeteilt werden. • Threadspezifische Information Jeder Thread umfasst eine Reihe von Informationen, die seinen aktuellen Zustand charakterisieren: Befehlszähler, aktuelle Registerwerte, Keller, Ablaufzustand des Thread. • Prozessspezifische Information Die nachfolgende Information/Ressourcen wird von allen Threads eines Prozesses geteilt. Jeder Thread des Prozesses kann sie verwenden bzw. darauf zugreifen. Adressraum, globale Variable, offene Dateien, Kindprozesse (z.B. erzeugt mit fork), eingetroffene Alarme bzw. Interrupts, Verwaltungsinformation Beispiel: Web-Server Ein Prozess kann mehrere Threads umfassen, die unterschiedliche Aufgaben übernehmen. Beispielsweise kann ein Web-Server einen Verteiler-Thread ("dispatcher") und mehrere Server-Threads ("worker-thread") umfassen. 23 Schlichter, TU München 3.2. SYNCHRONISATION Web-Serverprozess VerteilerThread ServerThread Benutzer Adressraum Anforderung Betriebssystem Netzwerk-Verbindung Auf diese Weise ist es möglich den Server als eine Menge von sequentiellen Threads zu realisieren. Der Verteiler-Thread ist eine unendliche Schleife, die die Schnittstelle für den Eingang von Service-Anforderungen darstellt. • Der Verteiler-Thread dient zur Annahme von Service-Anforderungen und gibt sie weiter an einen der Server-Threads zur Bearbeitung. • Alle Server-Threads nutzen den gemeinsamen Web-Cache. 3.2 Synchronisation Eine wichtige Systemeigenschaft betrifft die Synchronisation paralleler Ereignisse. Mehrere Prozesse (oder Threads) konkurrieren um eine gemeinsame Ressource (CPU), oder greifen auf gemeinsame Daten zu. 3.2.1 Beispiel: gemeinsame Daten P1 und P2 sind nebenläufige Prozesse, die in einem Multiprozessorsystem parallel ablaufen. Die Variable x ist gemeinsame Variable. Prozess P1 läuft auf CPU 0 mit Prozess P2 auf CPU 1 gleichzeitig ab. Das Problem ergibt sich auch bei quasiparallelem Ablauf (zeitliche Verschränkung der Arbeit der Prozesse). Z sei ein Zeitpunkt nach Ausführung der Aktionen A und B. Welchen Wert hat x zum Zeitpunkt Z? 24 Schlichter, TU München 3.2. SYNCHRONISATION Das Ergebnis des Ablaufs kann je nach zeitlichem Ablauf x = 1, 2, 3 sein. Der grundlegende Nichtdeterminismus der Nebenläufigkeit wegen der Asynchronität schlägt hier auf die Ergebnisse der Prozesse durch. int x; x = 0 Prozess P1 Prozess P2 A: x = x + 1 B: x = x + 2 Zeitpunkt Z Mögliche Abläufe Das Ergebnis ist vom zeitlichen Ablauf abhängig. Es sind folgende Fälle möglich: • Fall 1 P1 liest x = 0, erhöht, speichert x = 1; P2 liest x = 1, erhöht, speichert x = 3; => Wert von x = 3 • Fall 2 P2 liest x = 0, erhöht, speichert x = 2; P1 liest x = 2, erhöht, speichert x = 3; => Wert von x = 3 • Fall 3 P1 und P2 lesen x = 0; P1 erhöht, speichert x = 1; P2 erhöht, speichert x = 2; => Wert von x = 2 • Fall 4 P1 und P2 lesen x = 0; P2 erhöht, speichert x = 2; P1 erhöht, speichert x = 1; => Wert von x = 1 25 Schlichter, TU München 3.2. SYNCHRONISATION Verhinderung des Nichtdeterminismus nur dadurch möglich, dass man garantiert, dass die Veränderung von x in den beiden Prozessen unter wechselseitigem Ausschluss (engl. mutual exclusion) erfolgt. Der Zugriff auf gemeinsame Ressourcen, z.B. auf gemeinsame Variable, muss koordiniert werden. Bei exklusiven Ressourcen wird die Nutzung sequentialisiert. Prozess P1: main () { ....... region x do x = x + 1: end region ........ } 3.2.2 Prozess P2: main () { ....... region x do x = x + 2: end region ........ } Synchronisierungskonzepte Ziel: Einführung wichtiger Realisierungskonzepte zur Synchronisierung paralleler Abläufe. Dazu Konkretisierung des Prozessbegriffs. Anforderungen für wechselseitigen Ausschluss Folgende Anforderungen sind an eine Realisierung des wechselseitigen Ausschlusses (w.A.) zu stellen: • Die kritischen Abschnitte der Prozesse sind wechselseitig auszuschließen. • Eine Realisierung des w.A. darf nicht von einer Annahme über die Reihenfolge, in der die Prozesse ihre kritischen Abschnitte ausführen, abhängen. • Eine Realisierung des w.A. darf nicht von Annahmen über die Ausführungszeit der Prozesse abhängen. • Unter der Annahme, dass Prozesse nach endlicher Zeit ihre kritischen Abschnitte wieder verlassen, muss gelten, dass kein Prozess einen anderen Prozess unendlich lange daran hindern darf, seinen kritischen Abschnitt auszuführen. 26 Schlichter, TU München 3.2. SYNCHRONISATION Jede Realisierung des w.A. benötigt eine Basis, mit festgelegten atomaren, d.h. nicht teilbaren Operationen. Konzepte für wechselseitigen Ausschluss • Unterbrechungssperre Der Ablauf des Prozesses darf nicht unterbrochen werden. – In Ein-Prozessorsystemen (1 CPU) kann es ausreichend sein, mit Enable und Disable Interrupt Operationen dafür zu sorgen, dass der Prozess, der einen kritischen Abschnitt ausführt, dabei nicht unterbrochen wird. – Realisierung mit Unterbrechungssperre ist nützlich für den Betriebssystemkern, aber sollte nicht für allgemeine Benutzerprogramme zur Verfügung stehen. • Test-and-Set Operationen Test-and-Set Operationen (Test-And-Set-Lock, TSL) erlauben auf HardwareEbene (Maschinenbefehl) das Lesen und Schreiben einer Speicherzelle als atomare Operation. – Semantik eines Test-and-Set-Befehls Die Instruktion liest den Inhalt eines Speicherwortes in ein Register und schreibt einen Wert ungleich Null an die Adresse dieses Wortes. Diese beiden Operationen werden als atomare, unteilbare Sequenz ausgeführt. Sei a die zu untersuchende Speicherzelle; der Wert 1 in der Speicherzelle kann dahingehend interpretiert werden, dass der Zugang in den kritischen Bereich nicht möglich ist. Befehl "TSL R, a" entspricht dann Register R = inhalt von a; a = 1 Falls R = 1 ist, ist der kritische Bereich bereits belegt, andernfalls war er frei und er wurde vom ausführenden Prozess belegt. ∗ Problem: wie Atomarität bei Rechensystem mit mehreren CPUs gewährleistet? ∗ Lösung: Die CPU, die die TSL-Instruktion ausführt, blockiert den Speicherbus, um andere CPU’s (Multi-Prozessorumgebung) daran zu hindern, auf die Speichereinheit zuzugreifen. 27 Schlichter, TU München 3.2. SYNCHRONISATION • Dienste mit passivem Warten Unterscheidung zwischen aktivem Warten: Prozess muss periodisch selber prüfen, ob die Voraussetzungen zum Weiterarbeiten erfüllt sind. passivem Warten: Prozess wird in Warte-Zustand versetzt und aufgeweckt, wenn das Ereignis, auf das er wartet, eingetreten ist. – Methoden oder Dienste, so dass unter Mithilfe des Betriebssystems ein Prozess in den Zustand wartend übergeführt wird. – beim Eintreten eines passenden "Weckereignisses" wird der Prozess vom Betriebssystem vom Zustand wartend in den Zustand rechenbereit übergeführt. – Beispiel: Java wait und notify. • Semaphor-Konzept Das Semaphor-Konzept ermöglicht die Realisierung des w.A. auf einem höheren Abstraktionslevel als die bereits angesprochenen Hardwareoperationen. Zur Realisierung wird aber auf diese wieder zurückgegriffen. Realisierung von Semaphoren mit aktivem und passivem Warten möglich. • Monitor-Konzept Das Monitor-Konzept basiert auf der Idee, die in einem kritischen Bereich bearbeiteten Daten zusammen mit den darauf definierten Zugriffsoperationen in einer sprachlichen Einheit - dem Monitor - zusammenzufassen. soll Probleme, wie sie bei der Programmierung von Semaphoren auftreten, vermeiden. zu einem Zeitpunkt höchstens ein Prozess innerhalb des Monitors aktiv. 28 Schlichter, TU München 3.2. SYNCHRONISATION Gemeinsame Daten Warte schlange Operationen Initialisierungscode – Definition von Bedingungsvariablen zur Spezifikation anwendungsspezifischer Bedingungen. – Operationen auf Bedingungsvariable cond cond.wait(): Prozess wird wartend gesetzt. cond.signal(): ein wartender Prozess wird aktiviert. 3.2.3 Semaphore Semaphore wurden 1968 von Dijkstra eingeführt. Ein Semaphor (Signalmast) ist eine ganzzahlige Koordinierungsvariable s, auf der nur die drei vordefinierten Operationen (Methoden) zulässig sind: Initialisierung, Prolog P (kommt von protekt), Epilog V (kommt von vrej). Operationen Die Operationen P und V sind atomar; sie sind unteilbar und sie werden wechselseitig ausgeschlossen ausgeführt. Sei s die Koordinierungsvariable, dann sind die P und V Operationen wie nachfolgend definiert. Die Operation müssen mit Hilfe von Systemdiensten so realisiert werden, dass sie wechselseitig ausgeschlossen ausgeführt werden. Vorsicht: hier gibt es keine ganz einheitliche Definition in der Literatur für die beiden Operationen. Mögliche Realisierung auf Hardware-Ebene mittels des Test-and-Set Maschinenbefehls. 29 Schlichter, TU München 3.2. SYNCHRONISATION • Informelle Charakterisierung public void P (int s) { s = s - 1; if ( s < 0 ) { Prozess in die Menge der bzgl. s wartenden Prozesse einreihen } } public void V (int s) { s = s + 1; if ( s ≤ 0 ) { führe genau einen der bzgl. s wartenden Prozesse in den Zustand rechenwillig über } } • Binäres Semaphor: die Kontrollvariable s nimmt nur boolesche Werte an. man spricht auch von Mutex. – Mutex in Posix Ein Posix Mutex ist als binäres Semaphor eine einfache Sperre, die die Nutzung gemeinsamer Ressourcen absichert. pthread_mutex_init(mutex) ⇒ initialisiert und konfiguriert ein Mutex. pthread_mutex_lock(mutex) ⇒ entspricht der P-Operation; sperrt ein Mutex. pthread_mutex_unlock(mutex) ⇒ entspricht der V-Operation; gibt ein Mutex frei. Mutex Objekte und Semaphore mit Integer Werten stehen auch in Windows zur Verfügung. Einsatz von Semaphoren Notation: Zur Vereinfachung gehen wir im Folgenden von einem vordefinierten Typ semaphor(int s) aus, der die P und V Operationen als vordefinierte, atomare Methoden anbietet. Semaphor-Objekte werden als Instanzen bezüglich des Typs semaphor erzeugt, wobei bei der Instantiierung das Semaphor mit dem Parameter s initialisiert wird. • Zugang zu kritischen Abschnitten Realisierung der kritischen Abschnitte von Prozessen, in denen auf eine exklusiv benutzbare Ressource X zugegriffen wird: 1. Definition eines Semaphor-Objekts wa: semaphor(1), d.h. Initialisierung der Kontrollvariable des Semaphor-Objekts wa mit 1. 30 Schlichter, TU München 3.2. SYNCHRONISATION 2. Klammern der kritischen Abschnitte, in denen auf die Ressource X zugegriffen wird, mit P und V Operationen: wa.P Code mit Zugriffen auf X wa.V • Die Anforderungen an Lösungen des wechselseitigen Ausschlusses sind mit dem Semaphor-Konzept aus folgenden Gründen erfüllt: – Wechselseitiger Ausschluss für alle kritischen Abschnitte. Aufgrund der Initialisierung der Koordinierungsvariablen mit 1 kann sich stets nur ein Prozess in einem kritischen Abschnitt befinden. – keine Reihenfolge-Annahmen. – keine Ausführungszeit-Annahmen. – kein Verhungern. Beispiel Erzeuger-Verbraucher Im Modellierungsteil wurde das Erzeuger-Verbraucher-Problem bereits kurz vorgestellt. Der Erzeuger-Prozess E erzeugt Datenelemente und schreibt sie in einen Puffer W. Der Verbraucher-Prozess V liest Datenelemente aus dem Puffer und verarbeitet sie. Der Zugriff der beiden Prozesse auf den Puffer ist zu synchronisieren. Lösung dieses Problems mittels Semaphor. • Variante 1 Zugriff auf Puffer W erfolgt durch Semaphor wa: semaphor(1); Erzeuger E: while (true) { produziere wa.P schreibe nach W wa.V } Verbraucher V: while (true) { wa.P entnimm aus W, falls Element da; sonst warte wa.V verarbeite } 31 Schlichter, TU München 3.2. SYNCHRONISATION Problem: es kann eine Verklemmung auftreten, wenn der Verbraucher wa.P ausführt und warten muss, weil der Puffer kein Element enthält. • Variante 2 Einführen eines zusätzlichen Semaphors voll: semaphor(0), das die Datenelemente im Puffer zählt: Erzeuger E: while (true) { produziere wa.P schreibe nach W wa.V voll.V } Verbraucher V: while (true) { voll.P wa.P entnimm aus W wa.V verarbeite } Für den Erzeuger ergibt sich natürlich ein analoges Problem, falls der Puffer W nur eine beschränkte Kapazität besitzt. • Variante 3 Einführen eines zusätzlichen Semaphors leer: semaphor(n), das die Anzahl der freien Elemente im Puffer zählt: wa.semaphor(1); //kontrolliert den Zugang zum kritischen Bereich voll.semaphor(0); //zählt die Anzahl der Einheiten im Puffer leer.semaphor(n); //zählt die Anzahl der freien Pufferplätze Erzeuger E: Verbraucher V: while (true) { produziere Einheit; leer.P; wa.P; schreibe Einheit nach W; wa.V; voll.V; } while (true) { voll.P; wa.P; entnimm Einheit aus W wa.V leer.V; verarbeiteEinheit; } 32 Schlichter, TU München 3.2. SYNCHRONISATION Beispiel Philosophenproblem Zu den klassischen Synchronisationsproblemen zählt das Problem der speisenden Philosophen ("Dining Philosophers"). In einem Elfenbeinturm leben fünf Philosophen. Der Tageszyklus eines jeden Philosophen besteht abwechselnd aus Essen und Denken. Die fünf Philosophen essen an einem runden Tisch, auf dem in der Mitte eine Schüssel voller Reis steht. Jeder Philosoph hat seinen festen Platz an dem Tisch und zwischen zwei Plätzen liegt genau ein Stäbchen. Das Problem der Philosophen besteht nun darin, dass der Reis nur mit genau zwei Stäbchen zu essen sind. Darüber hinaus darf jeder Philosoph nur das direkt rechts und das direkt links neben ihm liegende Stäbchen zum Essen benutzen. Das bedeutet, dass zwei benachbarte Philosophen nicht gleichzeitig essen können. 3 2 2 3 1 4 4 0 1 0 • Realisierung mit Semaphoren – Variante 1 Für eine Lösung des Philosophenproblems seien die folgenden 5 Semaphore definiert: stab_0, stab_1, ...., stab_4, wobei jedes der 5 Semaphore mit 1 initialisiert ist. Jeder Philosoph j, mit j ∈ {0,...,4}, führe den folgenden Algorithmus aus: philosoph_j: while (true) { Denken; stab_i.P; mit i = j stab_i.P; mit i = j + 1 mod 5 Essen stab_i.V; mit i = j stab_i.V; mit i = j + 1 mod 5 } 33 Schlichter, TU München 3.2. SYNCHRONISATION – Variante 2 Nur vier Philosophen dürfen gleichzeitig zu ihrem linken Stäbchen greifen. Dies wird durch Einführung eines weiteren Semaphors tisch: semaphor(4), das mit 4 initialisiert wird, erreicht. Der "Anweisungsteil" jedes Philosophen wird zusätzlich mit tisch.P und tisch.V geklammert. Es ergibt sich also folgende Lösung: Jeder Philosoph j, mit j ∈ {0,...,4} führt den folgenden Algorithmus aus: philosoph_j: while (true) { Denken; tisch.P stab_i.P; mit i = j stab_i.P; mit i = j + 1 mod 5 Essen stab_i.V; mit i = j stab_i.V; mit i = j + 1 mod 5 tisch.V } 3.2.4 Synchronisierung von Java Threads Java unterstützt synchronisierte Methoden. public synchronized void methodname(...) { ... } Eine synchronisierte Methode kann nur exklusiv von einem Java Thread betreten werden. Beispiel TakeANumber Class Nur ein Thread kann zu einem Zeitpunkt eine Nummer ziehen class TakeANumber { private int next = 0; //next place in line public synchronized int nextNumber() { next = next + 1; return next; } //nextNumber } //TakeANumber 34 Schlichter, TU München 3.2. SYNCHRONISATION public class Customer extends Thread { private static int number = 1000; //initial customer ID private int id; private TakeANumber takeANumber; public Customer(TakeANumber gadget) { id = ++number; takeANumber = gadget; } //Customer constructor public void run() { try { sleep( (int)(Math.random() * 1000) ); System.out.println("Customer "+id+" takes ticket " + takeANumber.nextNumber()); } catch ...... } //run } //Customer public class Bakery { public static void main(String args[]) { System.out.println("Starting Customer threads"); TakeANumber numberGadget = new TakeANumber(); ......... for (int k = 0; k < 5; k++) { Customer customer = new Customer(numberGadget); customer.start(); } } // main } //Bakery Java Monitor Ein Monitor ist ein Java-Objekt, das synchronisierte Methoden enthält. • Ein Monitor stellt sicher, dass nur ein Thread zur Zeit in einer der synchronisierten Methoden sein kann. Bei Aufruf einer synchronisierte Methode wird das Objekt gesperrt. • Während das Objekt gesperrt ist, können keine anderen synchronisierten Methoden des Objekts aufgerufen werden. • Kritische Abschnitte können in Java als Objekte mit den zugehörigen synchronisierten Methoden spezifiziert werden. 35 Schlichter, TU München 3.3 3.3. VERKLEMMUNGEN Verklemmungen Mit Verklemmung (engl. deadlock) bezeichnet man einen Zustand, in dem die beteiligten Prozesse wechselseitig auf den Eintritt von Bedingungen warten, die nur durch andere Prozesse in dieser Gruppe selbst hergestellt werden können. Verklemmungen können durch die gemeinsame Verwendung von Ressourcen (synonym verwenden wir auch den Begriff Betriebsmittel), wie z.B. CPU, Arbeitsspeicher, E/A-Geräte, Dateien auftreten. Der Austausch von Information über gemeinsame Speicherbereiche ist eine häufige Situation (speicherbasierte Prozessinteraktion), die bei unkorrekter Verwendung von Synchronisationsoperationen (z.B. P und V bei Semaphoren) leicht zu Verklemmungen führen kann; siehe die Variante 1 des ErzeugerVerbraucher Lösungsansatzes. Dieser Abschnitt skizziert nur die Ansätze zur Erkennung, Vermeidung und Verhinderung von Verklemmungen. 3.3.1 Allgemeines Es lässt sich zeigen, dass die folgenden Bedingungen notwendig und hinreichend dafür sind, dass eine Verklemmung auftreten kann. 1. Die gemeinsam benutzbaren Ressourcen können nicht parallel genutzt werden, d.h. sie sind nur exklusiv benutzbar. 2. Die zugeteilten/belegten Ressourcen können nicht entzogen werden, d.h. die Nutzung ist nicht unterbrechbar. 3. Prozesse belegen die schon zugeteilten Ressourcen auch dann, wenn sie auf die Zuteilung weiterer Ressourcen warten, d.h. wenn sie weitere Ressourcen anfordern. 4. Es gibt eine zyklische Kette von Prozessen, von denen jeder mindestens eine Ressource belegt, die der nächste Prozess in der Kette benötigt, d.h. zirkuläre Wartebedingung. 3.3.2 Belegungs-Anforderungsgraph Die Zuteilung/Belegung und Anforderung von Ressourcen kann man sich an einem Graphen, dem Belegungs-Anforderungsgraph, veranschaulichen. Die Knoten sind die Prozesse und Ressourcen, die Kanten spiegeln Belegungen und Anforderungen wider. 36 Schlichter, TU München 3.3. VERKLEMMUNGEN • Beispiel Seien P = {P1, ... , Pn} Prozesse und R= {R1, ... , Rm} Ressourcen, z.B. n = 3 und m = 4. Beispiel eines Belegungs/Anforderungsgraphen. P1 fordert R1 belegt R2 3.3.3 P3 belegt P2 belegt R4 belegt fordert fordert R3 Verklemmungs-Ignorierung In vielen Systemen wird eine ’Vogel-Strauß’-Politik in bezug auf die Deadlockproblematik verfolgt, d.h. es werden keine Maßnahmen eingesetzt, sondern es wird gehofft, dass alles gut geht. In Unix wird diese Philosophie z.B. bei der Verwaltung der Prozesstabelle verfolgt. 3.3.4 Verklemmungs-Erkennung In der Praxis häufig angewendete Strategie: Verklemmungen in Kauf nehmen, sie erkennen und beseitigen. • Erkennungs-Algorithmus Ansatz 1: Suche nach Zyklen im Belegungs/Anforderungsgraph. Ansatz 2: Prüfen, ob es eine Reihenfolge für die Ausführung der Prozesse gibt, so dass alle Prozesse terminieren können. • Vorgehen für Ansatz 2 1. Starte mit Prozessmenge P, die alle Prozesse enthält, 2. suche Prozess p aus P, dessen zusätzliche Anforderungen im aktuellen Zustand erfüllbar sind, 3. falls gefunden, simuliere, dass p seine belegten Ressourcen wieder freigibt, 4. entferne p aus P und gehe zu 2 5. falls kein Prozess mehr in P, dann terminiert Suche: keine Verklemmung, 37 Schlichter, TU München 3.3. VERKLEMMUNGEN 6. falls P 6= Ø und in Schritt 2 kein Prozess mehr gefunden wird, dessen Anforderungen erfüllbar sind, dann terminiert die Suche; P enthält die Menge der verklemmten Prozesse. • Auflösung einer Verklemmung in der Regel durch Abbruch einzelner Prozesse. 3.3.5 Verklemmungs-Verhinderung Die Verhinderungssverfahren beruhen darauf, dass man durch die Festlegung von Regeln dafür sorgt, dass mindestens eine der für das Auftreten von Deadlocks notwendigen Bedingungen nicht erfüllt ist. • Festgelegte lineare Reihenfolge Bedingung "Zyklus tritt auf" in Belegungs-/ Anforderungsgraph darf nicht erfüllt werden. Dazu wird eine lineare Ordnung über den Ressourcen definiert: R1 < R2 < ... Rm. Die Prozesse dürfen dann Ressourcen nur gemäß dieser Ordnung anfordern, d.h. ein Prozess, der Ressource Ri belegt, darf nur Ressourcen Rj anfordern, für die gilt: Rj > Ri. • Andere Möglichkeiten sind: a) Zuteilung aller benötigten Ressourcen zu einem Zeitpunkt. b) zwangsweiser Entzug aller belegter Ressourcen, falls eine RessourcenAnforderung nicht erfüllt werden kann. c) Spooling: nur der Spooler Prozess hat als einziger die Ressource zugeteilt; Zugriffe anderer Prozesse gehen über diesen Prozess. Beispiel ist das Spooling von Druckaufträgen. 3.3.6 Verklemmungs-Vermeidung Die Vermeidungsverfahren basieren auf der Idee, die zukünftigen Betriebsmittelanforderungen von Prozessen zu analysieren (bzw. diese geeignet abzuschätzen) und solche Zustände zu verbieten (sie also zu verhindern), die zu Verklemmungen führen könnten. Ein Beispiel ist der Bankiers-Algorithmus, der 1965 von Dijkstra entwickelt wurde. 38 Schlichter, TU München 3.3. VERKLEMMUNGEN Veranschaulichung des Algorithmus Veranschaulichung des Verfahrens anhand eines Bankenszenarios. • Ausgangspunkt Idee: Verwaltung von nur einer Ressourcen-Klasse, nämlich den Bankkrediten. – Bankier besitzt festen Geldbetrag und verleiht Geld an seine Kunden. – Alle Kunden sind dem Bankier bekannt, jeder Kunde hat einen eigenen maximalen Kreditrahmen, der kleiner als die zur Verfügung stehende Geldmenge des Bankiers ist. – Bankier hat weniger Geld als die Summe dieser Kreditrahmen. – Kunden können jederzeit Geld in der Höhe ihres jeweiligen Kreditrahmens fordern, müssen aber ggf. in Kauf nehmen, dass der Bankier diese Forderung erst nach endlicher Zeit erfüllt. • Aufgabe des Bankiers Verleihen des Geldes so, dass jeder Kunde seine Geschäfte in endlicher Zeit durchführen kann und Kunden möglichst parallel bedient werden. Idee: Reihenfolge für Kreditvergabe finden, so dass selbst bei denkbar ungünstigsten Kreditforderungen die Durchführung aller Geschäfte sichergestellt ist. ungünstigster Fall: alle Kunden fordern Geld bis zu ihrem jeweiligen max. Kreditrahmen, ohne Kredite zurückzuzahlen. • Grobes Vorgehen 1. falls ein Kunde (Prozess) eine Anforderung hat, die aktuell erfüllbar ist, so teilt man das Geld (die Ressource) probeweise zu und 2. untersucht für den sich damit ergebenden Zustand, ob jetzt eine Verklemmung vorliegt, indem 3. für alle anderen Kunden von deren ungünstigsten Anforderungen ausgegangen wird und 4. ein Erkennungs-Algorithmus ausgeführt wird. Falls keine Verklemmung auftritt, kann die Zuteilung tatsächlich erfolgen, anderenfalls könnte bei einer Zuteilung ein Deadlock auftreten (muss aber nicht), weshalb die Anforderung nicht erfüllt wird. 39 Schlichter, TU München 3.3. VERKLEMMUNGEN • Beispiel Ausgangspunkt ist die folgende Situation der vier Kunden A, B, C, D (Einheiten jeweils in Tausend Euro): Kunde aktueller Kredit max. Kreditrahmen A 1 6 B 1 5 C 1 4 D 4 7 Es seien noch 3 Einheiten (Tausend Euro) in der Bank als Kredit verfügbar. – Annahme: Kunde C fordere eine weitere Einheit als Kredit an. Diese Anforderung wird probeweise zugeteilt und mündet nicht in einem Deadlock, da zuerst C (max noch 2 Einheiten bis Kreditrahmen) bedient werden kann. Wenn C seine Einheiten wieder zurückgezahlt hat, können B oder D und schließlich A bedient werden. 40 Schlichter, TU München 3.3.7 3.3. VERKLEMMUNGEN Vergleich der Ansätze Ansatz Erkennung Verhinderung Vermeidung Verfahren Vorteile periodischer Prozesserzeugung Aufruf des wird nicht verzöErkennungs gert; erleichtert Algorithmus interaktive Reaktion feste Reihefolge keine Verklembei der Zuteilung mungsanalyse zur Laufzeit notwendig; Überprüfung während Übersetzung Zuteilung aller keine PräempRessourcen auf tion (Entzug) einmal von Ressourcen notwendig; gut für Prozesse mit einzelner Aktivitätsphase (single burst) Bankierskeine PräempAlgorithmus tion (Entzug) von Ressourcen notwendig 41 Nachteile Verlust durch Abbruch keine inkrementellen Anfragen für Ressourcen möglich ineffizient; verzögert Prozesserzeugung; Bedarf für Ressourcen muss bekannt sein zukünftiger Bedarf muss bekannt sein; Prozesse können längere Zeit blockiert werden Kapitel 4 Prozess- und Prozessorverwaltung Ein Prozess ist der Ablauf eines Programms in einem Rechensystem. Dieser Ablauf ist eine Verwaltungseinheit im jeweiligen Betriebssystem. 4.1 Fragestellungen Dieser Abschnitt gibt eine kurze Einführung in eine der wichtigen Verwaltungsaufgaben eines Betriebssystems: • Verwaltung von Prozessen. • Verwaltung des Prozessors, d.h. Zuteilung der CPU an rechenbereite Prozesse (Scheduling). • Unterbrechungskonzept. 4.2 Prozessverwaltung Dieser Abschnitt behandelt das Prozesskonzept, Datenstrukturen zur Beschreibung des aktuellen Prozesszustandes sowie Dienste zum Aufruf von Systemfunktionen. Prozesse repräsentieren eine Aktivität; sie haben ein Programm, Eingaben, Ausgaben und einen Zustand. 42 Schlichter, TU München 4.2.1 4.2. PROZESSVERWALTUNG Prozesskonzept Wir unterscheiden Benutzerprozesse, die Anwendungsprogrammen in Ausführung entsprechen, und Systemprozesse, die Programme/Dienste des Betriebssystems durchführen. a) Jeder Prozess besitzt einen eigenen Prozessadressraum. b) Spezielle Systemprozesse sind die Dämonen (engl. daemon); das sind Hilfsprozesse, die ständig existieren, die meiste Zeit aber passiv sind. Dienste der Prozessverwaltung Die Prozesse werden durch das Betriebssystem verwaltet. • Auslösende Ereignisse für die Erzeugung eines Prozesses Initialisierung des Systems. Systemaufruf zum Erzeugen eines Prozesses durch einen anderen Prozess. Benutzeranforderung zum Starten eines neuen Prozesses (Start einer Applikation). Auslösung eines Stapelauftrags (Batch Job). • Formen der Terminierung von Prozessen Normale Beendigung (freiwillig). Vorzeitige Beendigung bei einem durch den Prozess selbst erkannten Fehler (freiwillig). Vorzeitige Beendigung bei einem katastrophalen Fehler, erkannt durch das BS (unfreiwillig). Terminierung durch einen anderen Prozess (unfreiwillig). • Prozess-Auswahl, Strategien zur Prozessorzuteilung: Scheduling. • Prozessor-Anbindung; Dispatching. Prozesskontrollblock Jeder Prozess muss als eine Verwaltungseinheit beschrieben sein. Ein Prozess wird durch seinen Prozess-Kontext und dieser durch den Prozesskontrollblock (PCB) beschrieben. Ein PCB wird meist programmiersprachlich als Verbund (struct) spezifiziert. Ein PCB (process control block) enthält i.d.R. folgende Informationen: 43 Schlichter, TU München 4.2. PROZESSVERWALTUNG • eindeutiger Name, z.B. fortlaufende Nummerierung des Prozesses (z.B. pid in Unix) • Name des Benutzers, dem der Prozess zugeordnet ist • der momentane Prozesszustand (wartend, rechnend, rechenwillig, ...) • falls der Prozess rechnend ist, Angabe der zugeordneten CPU • falls der Prozess wartend ist, eine Spezifikation des Ereignisses, auf das der Prozess wartet (z.B. Adresse eines Semaphors). • die Ablaufpriorität des Prozesses • die Inhalte der programmierbaren Register (die Anzahl ist abhängig von der jeweiligen CPU-Architektur), z.B. Kellerpointer. • die Inhalte der Register, in denen die Anfangsadresse und Länge der prozessspezifischen Speicherabbildungstabellen enthalten sind (virtuelle Adressierung). • das Programmstatuswort (PSW).Beispiele für dem Inhalt des PWS’s sind der Ablaufmodus (Benutzer- oder Systemmodus), die momentane Ablaufpriorität, die Adressierungsart im Benutzermodus (virtuelle oder direkte Adressierung) und die Ergebnisse der letzten Vergleichsoperation auf Maschinenebene (sogenannte Condition-Code Register, z.B. das N-Register (Ergebnis der letzten Operation negativ). • PCB unter Linux ist durch die Struktur task_struct spezifiert; definiert unter include/linux/sched.h . Prozesslisten Die Prozesse werden in Zustandslisten verwaltet, die als verkettete Liste der PCBs realisiert sind. für E/A-Geräte (z.B. Platte, Terminal) existiert i.d.R. jeweils eine eigene Warteschlange, die die PCBs der wartenden Prozesse enthält. 44 Schlichter, TU München 4.2. PROZESSVERWALTUNG Prozessidentifikation Rechnend Registerzustand Scheduling Information (z.B. Priorität) Rechenwillig Adressrauminformation Ready-Queue Sonstiges Wartend nächster PCB Prozesskontrollblock PCB Zustandsmodell Das Prozess-Zustandsmodell unterscheidet neben den bereits vorgestellten Zuständen rechenwillig, rechnend, wartend auch den Zustand ausgelagert. Letzterer Zustand tritt ein, wenn der Adressraum aufgrund Speichermangels aus dem Arbeitsspeicher auf den Hintergrundspeicher verlagert wird ("swapping"). resign add retire assign rechenwillig rechnend block ready wartend swap out swap in ausgelagert Zustandsübergänge sind: add: ein neu erzeugter Prozess wird zu der Menge der rechenwilligen Prozesse hinzugefügt; assign: als Folge eines Kontextwechsels wird dem Prozess die CPU zugeordnet; 45 Schlichter, TU München 4.2. PROZESSVERWALTUNG block: aufgrund eines EA-Aufrufs oder einer Synchronisationsoperation wird der Prozess wartend gesetzt; ready: nach Beendigung der angestoßenen Operation wechselt der Prozess in den Zustand rechenwillig; er bewirbt sich erneut um die CPU; resign: dem rechnenden Prozess wird die CPU entzogen; er bewirbt sich anschließend erneut um die CPU; retire: der aktuell rechnende Prozess terminiert; swap out: der Prozess wird auf die Festplatte ausgelagert; swap in: der Prozess wird von der Festplatte in den Arbeitsspeicher geladen. Prozesserzeugung Ein Prozess kann andere Prozesse erschaffen. Diese sind die Kindprozesse (child process) und der Erschaffer ist der Vater (parent process). Vater kann auf Beendigung von Kind warten, oder parallel weiterlaufen. • Prozesserzeugung: 2 Vorgehensweisen Windows NT: Vaterprozess veranlasst eine Reihe von Systemaufrufen, die das Kind entstehen lassen. Unix: Vater klont sich mit Systemaufruf fork(); Kind ändert selbst sein Aufgabe. • Unix Prozesserzeugung Aufruf von fork() führt zu einem fast exakten Duplikat des Vaterprozesses. Unterschiede sind unterschiedlicher process identifier (PID) der Ergebniswert von fork() Vater: PID des Kindprozesses Kind: 0 – Beispielprogramm #include <stdio.h> 46 Schlichter, TU München 4.2. PROZESSVERWALTUNG int main(int argc, char *argv[]) { char *myname = argv[1]; int cpid = fork(); if cpid == 0 { printf("The child of %s is %d\n", myname, getpid()); ....... return (0); } else { printf("My child is %d\n", cpid); /* wird vom Vaterprozess durchlaufen */ ..... return(0); } } – Kind hat vieles mit dem Vater gemeinsam: liest dieselben Dateien, gleicher Benutzername, benutzt dieselben Daten – Unix Kind fängt mit dem Code des Vaters an und ändert sich dann Systemaufruf exec(): ersetzt das Programmbild des Vaters mit einem anderen. Beispielprogramm für exec #include <stdio.h> int main(int argc, char *argv[]) { char *myname = argv[1]; int cpid = fork(); if cpid == 0 { int rc; rc = execl("/bin/ls", "ls", "-l", (char *) 0); printf("Fehler bei execl Aufruf: %d\n", rc); exit(1) } else { /* wird vom Vaterprozess durchlaufen */ } } – Prinzipablauf Mit der Systemfunktion wait wartet der Vaterprozess auf den Kindprozess. wait vor Beendigung des Kindes: Vater ist blockiert. wait nach Beendigung des Kindes: Kind wird nach Beendigung zum Zombieprozess. 47 Schlichter, TU München 4.2. PROZESSVERWALTUNG Kind exit Vater Vater Vater fork wait Kind exit Zombieprozess Vater Vater Vater wait fork • Linux unterstützt den Systemaufruf clone() zur Erzeugung neuer ThreadKopien. Prozesse und Vererbung Bei der Verwaltung von Vater-/Kindprozess sind eine Reihe von Entscheidungen zu treffen: • Ausführung Vaterprozess und Kind werden gleichzeitig ausgeführt, oder der Vaterprozess wartet darauf, dass das Kind beendet wird • Ressourcen Vater und Kind teilen sich alle Ressourcen. Vater und Kind teilen sich einen Teil der Ressourcen. Vater und Kind haben keine Ressourcen gemeinsam. • Adressraum Das Kind ist ein Duplikat des Vaters. Das Kind führt durch automatisches Laden ein neues Programm aus (execSystemaufruf). • Threads Das Kind dupliziert alle Threads des Vaters. Das Kind dupliziert nur den Thread des Vaters, der die fork-Operation ausgelöst hat. 48 Schlichter, TU München 4.2.2 4.2. PROZESSVERWALTUNG Dispatcher Aufgabe des Dispatchers: Realisieren der Zustandsübergänge zwischen rechnend und rechenwillig: Prozessor binden und entbinden. Dazu ist ein Kontextwechsel erforderlich. Kontextwechsel CPU wird entzogen und einer anderen Aktivität zugeteilt; ein Kontextwechsel ist erforderlich, falls der rechnende Prozess P1 in den Zustand wartend oder z.B. durch Prozessorentzug in den Zustand rechenwillig übergeführt wird. • Problem aktueller Ausführungskontext des Prozesses muss gesichert werden und Kontext des nächsten rechenbereiten Prozesses muss geladen werden. Achtung: je umfangreicher ein PCB ist, desto "teurer" sind Prozesswechsel, d.h. das Umschalten der CPU zwischen den Prozessen. Threads Threads haben einen sehr viel kleineren Kontext ⇒ Umschalten zwischen Threads innerhalb eines Prozesses sehr schnell, da Adressraum und andere Ressourcen (z.B. Dateien) gemeinsam genutzt werden. 4.2.3 Arbeitsmodi Ziel für den Betrieb von Rechensystemen: kontrollierter Zugriff auf Hardwarekomponenten nur durch BS. Dadurch soll verhindert werden, dass Benutzer oder Softwaresysteme Hardwarekomponenten unsachgemäß nutzen, und implizit andere nebenläufige Aktivitäten schädigen. Lösung: alle Zugriffe auf Hardware nur über privilegierte Befehle zulässig; Frage: wer darf privilegierte Befehle ausführen ⇒ Antwort: Prozesse in einem privilegierten Modus. Herkömmlich unterscheidet man zwischen dem Benutzer- (engl. user mode) und dem Systemmodus (engl. kernel mode). • Benutzermodus 49 Schlichter, TU München 4.2. PROZESSVERWALTUNG Es sind nur die nicht privilegierten Befehle verfügbar. Damit ist der Zugriff auf Prozessadressraum und unkritische Register, wie Befehlszähler, Indexregister möglich. Benutzerprozesse werden im Benutzermodus ausgeführt. Kritische Register, über die der Kontext eines Prozesses beeinflusst werden kann (z.B. Ablaufpriorität, Arbeitsmodus) können nur im Systemmodus verändert werden. Wird versucht, einen privilegierten Befehl auszuführen, gibt es einen Befehlsalarm. • Systemmodus Es sind auch die privilegierten Befehle verfügbar (z.B. Anhalten der Maschine, Verändern der Ablaufpriorität). Die Dienste des Betriebssystemkerns werden im Systemmodus ausgeführt. • Nutzung der Hardware-Komponenten nur über Dienste des BS: Aufruf eines BS-Dienstes über spezielle Befehle: den Systemaufruf. 4.2.4 Systemaufrufe Ein Systemaufruf ist eine Funktion, die von einem Benutzerprozess aufgerufen wird, um einen BS-Kerndienst aufzuführen. 1. Der Systemaufruf überprüft die übergebenen Parameter und bildet daraus eine Datenstruktur, um die Daten an den BS-Kern weiterzureichen. 2. Danach wird eine spezielle Instruktion, ein Software Interrupt (Trap), ausgeführt. Diese Instruktion identifiziert über einen Operanden den gewünschten Systemdienst. 3. Bei Ausführung der Trap-Instruktion wird der Zustand des Benutzerprozesses gerettet und es findet ein Wechsel in den Systemmodus statt. • Beispiel Lesen von Daten aus einer Datei und Kopieren in eine andere Datei. Dabei treten die folgenden Systemaufrufe auf: (1) (2) (3) (4) (5) (6) Schreiben des Prompts auf Bildschirm: Angabe der Dateinamen Lesen der Tastatureingabe (bzw. Analoges bei Mouse-Eingabe) Öffnen der zu lesenden Datei (open) Erzeugen der neuen Datei ggf. Fehlerbehandlung: Nachricht auf Bildschirm Schleife: Lesen von Eingabedatei (ein Systemaufruf) und schreiben in zweite Datei (auch Systemaufruf) (7) Schließen beider Dateien (8) Ausgabe auf Bildschirm 50 Schlichter, TU München 4.2. PROZESSVERWALTUNG Durch die Verwendung von Laufzeitroutinen ergibt sich eine höhere Abstraktionsebene ⇒ Aufruf einer Routine, die die notwendigen Systemaufrufe durchführt. 4.2.5 Realisierung von Threads Es existieren zwei grundlegende Ansätze, Threads in einem Rechensystem zu realisieren: im Benutzer-Adressraum (Benutzermodus) oder im SystemAdressraum (Systemmodus). im Benutzer-Adressraum Der BS-Kern verwaltet nur single-threaded Prozesse. Prozess Thread Benutzer Adressraum (Benutzermodus) System Adressraum (Systemmodus) BS-Kern Laufzeitsystem Prozesstabelle Thread tabelle • Threads werden durch Laufzeitsystem im Benutzeradressraum verwaltet. Eine Thread-Tabelle speichert Informationen (Register, Zustand, etc.) über Threads pro Prozess. • Prozessorzuteilung im BS-Kern erfolgt an Prozesse. Laufzeitsystem bestimmt, welcher Thread rechnend gesetzt wird. • Problem: Systemaufruf eines Threads blockiert die anderen Threads des Prozesses. • Problem: wie wird einem Thread die CPU entzogen? 51 Schlichter, TU München 4.3. PROZESSORVERWALTUNG im System-Adressraum Neben den Prozessen werden im BS-Kern auch alle Threads verwaltet. Prozess Thread Benutzer Adressraum (Benutzermodus) System Adressraum (Systemmodus) BS-Kern Thread tabelle Prozesstabelle • Thread-Tabelle speichert Informationen (Register, Zustand, etc.) über Threads. • Prozessorzuteilung im BS-Kern erfolgt an Threads. • Der Systemaufruf eines Threads blockiert nicht die anderen Threads des Prozesses. 4.3 Prozessorverwaltung Eine wesentliche Aufgabe der Prozessorverwaltung besteht darin zu entscheiden, welcher der um den bzw. die Prozessor(en) konkurrierenden Prozesse (bzw. Threads) zu einem Zeitpunkt an den bzw. die Prozessor(en) gebunden wird. Dazu steht die BS-Komponente Scheduler zur Verfügung. • Prozessablauf besteht aus einer Sequenz von alternierenden CPU- und E/APerioden. • Zeitliche Verschränkung der Prozessbearbeitung bei einer CPU. 52 Schlichter, TU München 4.3. PROZESSORVERWALTUNG Zeit Zuweisung CPU an A A hat CPU A hat CPU Prozess A Unterbrechung BS-Kern hat CPU BS-Kern BS-Kern hat CPU Unterbrechung B hat CPU Prozess B Zuweisung CPU an B 4.3.1 Kriterien Der Scheduler wählt aus der Menge der rechenwilligen Prozesse den nächsten auszuführenden Prozess aus. Es existieren unterschiedliche Verfahren die von der jeweiligen Prozessorverwaltungsstrategie abhängen. Mögliche Leistungskriterien für ein Schedulingverfahren: • Fairness. • Effizienz, Prozessorauslastung. • Antwortzeit für interaktive Benutzer (Dialogverarbeitung). • Wartezeit, insbesondere für Batch-Jobs (Stapelverarbeitung). • Ausführungszeit, d.h. Zeitspanne von Auftragsbeginn bis Auftragsende. • Abschlusszeit, insbesondere für Realzeitsysteme. • Durchsatz, Anzahl der Aufträge pro Zeiteinheit. Kriterien der Betriebsarten Die Ziele der Schedulingverfahren hängen von der Umgebung und den Betriebsarten des Rechensystems ab. 53 Schlichter, TU München 4.3. PROZESSORVERWALTUNG • Alle Systeme Fairness - jeder Prozess bekommt Rechenzeit der CPU. Balance - alle Teile des Systems sind ausgelastet. Policy Enforcement - Scheduling Policy wird nach außen sichtbar durchgeführt. • Stapelbetrieb Durchsatz - maximiere nach Aufträge pro Zeiteinheit. Ausführungszeit - minimiere die Zeit von Start bis zur Beendigung. CPU-Belegung - belege CPU konstant mit Aufträgen. • Dialogbetrieb - interaktive Systeme Antwortzeit - antworte schnellstmöglich auf Anfragen. Proportionalität - Erwartungshaltung der Nutzer berücksichtigen. • Echtzeitsysteme Abschlusszeit - kein Verlust von Daten. Vorhersagbarkeit - Qualitätsverlust bei Multimedia vermeiden. 4.3.2 Scheduling-Strategien Es werden zwischen zwei Klassen unterschieden: nicht-unterbrechende (nonpreemptive) und unterbrechende Strategien (preemptive). nicht unterbrechend: Scheduling nur dann möglich, wenn der rechnende Prozess blockiert wird oder wenn er terminiert, d.h. Prozess behält CPU bis er sie selber abgibt. Beispiel: Microsoft Windows 3.x; unterbrechende Strategien erst ab Windows 95 unterbrechend: Unterbrechung beim Eintreten von speziellen Ereignissen, u.a. Eintreffen eines Prozesses mit höherer Priorität oder Prozess geht in Wartezustand. 54 Schlichter, TU München 4.3. PROZESSORVERWALTUNG Zeitscheibenstrategie Die Zeitscheibenstrategie (Round Robin) ist unterbrechend. Ziel ist die gleichmäßige Verteilung der Rechenzeit auf rechenwillige Prozesse. Round Robin ist eine weit verbreitete preemptive Schedulingvariante. Das Verfahren ordnet jedem rechenwilligen Prozess ein definiertes Zeitquantum (Zeitscheibe) zu. In 4.3 BSD Unix beträgt z.B. die Zeitscheibe 100 ms. Nach dem Kontextwechsel ist der Prozess entweder bis zum Ablauf des Zeitquantums oder bis zum Auftreten einer blockierenden Systemfunktion im Besitz der CPU. Alle rechenwilligen Prozesse werden in einer FIFO-Warteschlange verwaltet. Nach Ablauf der Zeitscheibe wird der Prozess am Ende der FIFO-Warteschlange eingereiht. • Es werden die Prozesse an den Prozessor jeweils für ein festgelegtes Zeitquantum q gebunden und spätestens nach dem Ablauf dieser Zeitspanne wird den Prozessen der Prozessor wieder entzogen. • zyklisches Bedienen der Prozesse (Round Robin). • Ready-Queue (Liste der rechenwilligen Prozesse) als zyklische Warteschlange realisiert. • Wahl des Zeitquantums: falls q zu klein: viele unproduktive Kontextwechsel. falls q zu groß: Round Robin wird zu einem reinen FCFS Scheduling (First Come First Served), da die Wahrscheinlichkeit für einen Aufruf eines blockierenden Systemdienst steigt. Typische Werte für q: 10 bis 100 Millisekunden. • Für q = 100 ms gilt bei 1 MIPS Maschine (Million Instructions/Second): ca. 100.000 Instruktionen/q. Prioritäten Diese Strategie ist i.a. unterbrechend. Sie basiert darauf, an die Prozesse Prioritäten zu vergeben. Die Prioritätenvergabe kann dabei statisch oder dynamisch sein. Die Prioritätenstrategie kann unterbrechend und nicht-unterbrechend sein. Im ersten Fall wird der Ablauf eines Prozesses unterbrochen, wenn ein anderer Prozess mit höherer Priorität rechenwillig wird. Im zweiten Fall behält der Prozess die CPU solange bis er entweder eine blockierende Systemfunktion aufruft oder die CPU freiwillig abgibt. • Prioritäten sind i.a. ein festgelegter Zahlenbereich, z.B. 0, ..., 7. 55 Schlichter, TU München 4.3. PROZESSORVERWALTUNG • Statische Prioritätenvergabe jeder Prozess besitzt für die Dauer seiner Existenz eine feste Priorität. Problem: Gefahr des Verhungerns von Prozessen mit niedriger Priorität Lösung: Erhöhung der Priorität von lange wartenden Prozessen, d.h. dynamische Prioritäten. • Dynamische Prioritätenvergabe die Prioritäten der Prozesse können sich dynamisch verändern, d.h. sie werden in gewissen Zeitabständen neu berechnet. Idee: lange Wartezeiten berücksichtigen (Erhöhen die Priorität). Prozesse mit großem CPU-Verbrauch sinken in Priorität. E/A-intensive Prozesse steigen in Priorität (damit E/A-Geräte und CPU parallel genutzt werden). • Zeitscheibenstrategien und Prioritätenvergabe können zu effizienten Verwaltungsstrategien kombiniert werden. • Windows XP Scheduling Windows XP nutzt eine Prioritäten-basierte, unterbrechende Strategie. Prozess/Thread mit höchster Priorität wird ausgeführt, bis er terminiert, oder er seine Zeitscheibe ausgeschöpft hat, oder eine Blockierung (Systemaufruf, E/A) auftritt. Es werden Prioritäten von 0 - 31 unterschieden, die in verschiedene Klassen eingeteilt werden zeit kritisch höchste über normal normal unter normal niedrigst idle Echtzeit hoch normal 15 über normal 15 idle 15 unter normal 15 31 26 25 15 14 12 11 10 9 8 7 6 5 24 23 13 12 10 9 8 7 6 5 4 3 22 16 11 1 8 1 6 1 4 1 2 1 56 15 Schlichter, TU München 4.3. PROZESSORVERWALTUNG First-Come First-Served Dieses nicht-unterbrechende Verfahren (FCFS) teilt einen Prozessor in der Reihenfolge des Auftragseingangs zu. Ready-Queue wird als FIFO-Liste verwaltet; Verfahren einfach zu realisieren. • Ein Kontextwechsel findet nur statt, wenn der Prozess eine blockierende Systemfunktion aufruft oder der Prozess die CPU freiwillig abgibt. • Es kann eine hohe CPU Auslastung erreicht werden. • Problem: Durchschnittliche Wartezeit ist hoch. Beispiel: Prozesse P1,P2,P3 kommen nahezu gleichzeitig zum Zeitpunkt 0 an; Dauer ihrer Berechnungszeiten: P1: 24 ms, P2: 3ms, P3: 3ms; bei Reihenfolge P1, P2, P3: mittlere Wartezeit: (0 + 24 + 27)/3 = 17 ms bei Reihenfolge P2, P3, P1 mittlere Wartezeit (0+3+6)/3 = 3 ms Shortest-Jobs-First Dieses Verfahren (SJF) führt die Prozessorzuteilung in der Reihenfolge der wachsenden Rechenphasen ("CPU-Burst") zu, d.h. Prozess mit kürzester, nächster Rechenphase erhält Prozessor als nächster. • anwendbar, falls die Dauer der nächsten Rechenphase bis E/A-Befehl, Interrupt etc. bekannt ist. • Beispiel: P1: 6ms, P2: 8ms, P3: 7ms, P4: 3ms Schedule bei SFJ : P4, P1, P3, P2; Wartezeit: (3+16 +9 +0) /4 = 7 ms bei FCFS: 10.25 ms (P1 vor P2 vor P3 vor P4) • Problem: Kenntnis über die Bedienzeiten erforderlich. Für Stapelbetrieb geeignet, da dort Information über Rechenzeiten zur Verfügung stehen (Benutzer geben bei Batch-Jobs Rechenzeit an). • Für interaktive Prozesse wird die Länge der nächsten Rechenphase ("Burst") geschätzt: n X Sn+1 = 1/n Ti i=1 Ti = Ausführungszeit der i-ten Rechenphase. 57 Schlichter, TU München 4.3. PROZESSORVERWALTUNG Si = Schätzung für die i-te Rechenphase. S1 = Schätzung für die erste Rechenphase. Anpassung der Berechnung Sn+1 = (1/n) * Tn + (n-1)/n * Sn 4.3.3 Thread Scheduling Die Prozessorzuteilung von Threads hängt von deren Art der Realisierung ab. User-Threads Realisierung der Threads im Benutzeradressraum ⇒ Kern hat keine Kenntnis bzgl. der Threads. BS-Scheduler wählt nur Prozess aus. Laufzeitsystem des Prozesses wählt rechenwilligen Thread des Prozesses aus; es kann ein beliebiges → Scheduling-Verfahren (siehe Seite 54) für Prozesse verwendet werden. • Java Virtual Machines verwenden unterbrechendes Prioritäten-Scheduling für Threads; 10 ist die höchste und 1 die niedrigste Priorität; Kernel-Threads Realisierung der Threads im Systemadressraum ⇒ BS-Scheduler wählt den nächsten auszuführenden Thread aus. a) Ist ausgewählter Thread demselben Prozess zugeordnet wie der vorher rechnende Thread ⇒ geringer Kontextwechsel. b) Ist ausgewählter Thread nicht demselben Prozess zugeordnet wie der vorher rechnende Thread ⇒ aufwendiger Kontextwechsel. 4.3.4 Mehrschichtiges Scheduling Der Scheduler wählt einen der rechenwilligen Prozesse aus. Da diese aber u.U. nicht alle im Arbeitsspeicher vorliegen (Speicherknappheit) und ein Einlagern eines Prozesses von der Platte in den Arbeitsspeicher aufwendig ist, verfügen Systeme häufig über ein Mehr-Schichten Scheduling. 58 Schlichter, TU München 4.3. PROZESSORVERWALTUNG • Short-Term-Scheduler (CPU Scheduler) Auswahl eines geeigneten Prozesses aus der Ready-Queue; wird häufig aufgerufen; Verfahren siehe oben. • Long-Term-Scheduler Auswahl rechenwilliger neuer Aufträge (meist Jobs aus dem Hintergrundbetrieb (batch)) und Einlagerung in den Arbeitsspeicher; Einfügen der Prozesse in die Ready-Queue. • Graphische Darstellung neue Aufträge Long-term Scheduler ausgeswappte Prozesse swap-out swap-in Ready Queue CPU CPU Scheduler E/A-Befehl E/A-Warteschlange Zeitscheibe abgelaufen sleep-Befehl Zeit-InterruptWarteschlange Ausführung im BS-Kern 59 Systemaufruf fertig Schlichter, TU München 4.3.5 4.3. PROZESSORVERWALTUNG Echtzeit Scheduling In Multimedia-Umgebungen treten die zu verarbeitenden kontinuierlichen Daten (Empfangen, Dekodierenen und Anzeigen von Videoframes) in bestimmten, meist periodischen Zeitabständen auf. Die Operationen auf diese Daten wiederholen sich dabei immer wieder und sollen bis zu einem gewissen Zeitpunkt abgeschlossen sein. Prozesse in Multimedia-Anwendungen führen oft zeitkritische Operationen aus. Bzgl. des Scheduling existieren zwei gegensätzliche Ziele: a) ein unkritischer Prozess sollte nicht dauerhaft blockiert werden, weil zeitkritische Prozesse eine Ressource gänzlich auslasten. b) zeitkritische Prozesse dürfen nicht durch Scheduling-Verfahren (RoundRobin oder Prioritäten) am zeitkritischen Fortschritt gehindert werden ⇒ Einhaltung von Zeitvorgaben. • Zuordnung von Kenngrößen zu zeitkritischen Prozessen Bereitzeit (ready time): frühestmöglicher Ausführungsbeginn einer Aktivität. Frist (deadline): spätester Zeitpunkt für die Beendigung einer Aktivität. Ausführungszeit: worst-case Abschätzung für das zur vollständigen Ausführung einer Aktivität notwendige Zeitintervall. • Earliest Deadline First (EDF) Der Prozessor wird immer dem Prozess mit der am nächsten in der Zukunft liegenden Frist zugeordnet. Es existieren die beiden Varianten: nichtunterbrechend und unterbrechend. – nicht-unterbrechend Eine Prozessorzuordnung bleibt bis der Prozess eine blockierende Systemfunktion aufruft oder freiwillig die CPU abgibt. Neue eintreffende Prozesse mit kürzeren Fristen werden erst beim nächsten Scheduling berücksichtigt. – unterbrechend Diese Variante führt einen Kontextwechsel durch, wenn ein Prozess mit einer kürzeren Frist rechenwillig wird. • Rate-Monotonic Scheduling Rate-Monotonic Scheduling (RMS) ist für periodische Prozesse; RMS ordnet Prioritäten in Abhängigkeit von der Periode zu. 1) Prozesse mit der höchsten Frequenz (kleinste Periode) erhalten die höchste Priorität. 2) Prozesse mit der geringsten Frequenz (längste Periode) erhalten die niedrigste Priorität. 60 Schlichter, TU München 4.4. UNTERBRECHUNGSKONZEPT – Auswahl der Prozesse anhand ihrer Priorität. – hochfrequente Prozesse werden minimal verzögert. – Zerstückelung niederfrequenter Prozesse, da sie häufig wegen hochfrequenter Prozesse unterbrochen werden. 4.4 Unterbrechungskonzept Die optimale Ausnutzung und Auslastung aller Geräte eines Rechensystems legt Mehrprogrammbetrieb nahe. Zerlegung der Ausführungsphasen eines Programms in viele Einzelteile; - Aufbrechen der Ausführung eines Prozesses in mehrere Phasen: u.a. Rechnen, E/A, Synchronisieren mit Partner. - Die Ausführung der Programme wird in der Regel mehrfach unterbrochen. 4.4.1 Motivation Ursachen für Unterbrechungen zugeteilte Prozessorzeit ist aufgebraucht; benötigte Ressourcen stehen aktuell nicht zur Verfügung; ein E/A-Gerät meldet sich zurück; ein Fehler tritt auf, z.B. Division durch 0; Systemaufruf (wurde bereits als spezielle Unterbrechung eingeführt); • Bei einer Unterbrechung wird ein gerade aktiver Prozess unterbrochen und eine Unterbrechungsbehandlung durchgeführt. Nach Beendigung der Unterbrechungsbehandlung kann prinzipiell ein beliebiger rechenbereiter Prozess fortgesetzt werden. • Es ist erforderlich, bei der Unterbrechung den CPU Status des gerade aktiven Prozesses für die spätere Fortsetzung zu speichern. • Forderung: Eine Unterbrechung muss so kontrolliert erfolgen, dass ein definierter Prozessstatus festgehalten werden kann. 4.4.2 Unterbrechungsarten Die normale Programmausführung eines Prozessors kann auch durch mehrere Arten von Unterbrechungen verändert werden. Man unterscheidet zwischen synchronen und asynchronen Unterbrechungen. 61 Schlichter, TU München 4.4. UNTERBRECHUNGSKONZEPT Unterbrechung synchron Trap asynchron Alarme (Exception) Interrupt Externe, asynchrone Unterbrechungen Dies sind Unterbrechungen (Interrupts), die von außerhalb des zu unterbrechenden Prozesses ausgelöst werden, z.B. E/A-Kanal-"Endmeldung". • Der Ablauf im Rechnerkern (RK) wird unterbrochen und eine Unterbrechungsanfangsbehandlung des Betriebsystemkerns wird aktiviert. E/A-Kanal 2 CPU (RK) BS-Kern Ende E/A Auftrag Unterbrechungsbehandlung (UBH) Interne, synchrone Unterbrechungen Dies sind Unterbrechungen (Alarme, Exceptions), die durch den zu unterbrechenden Prozess selbst ausgelöst werden, z.B. Division durch 0. 62 Schlichter, TU München 4.4. UNTERBRECHUNGSKONZEPT • Der Ablauf im RK wird unterbrochen und eine Unterbrechungsanfangsbehandlung des Systemkerns wird aktiv. CPU (RK) BS-Kern Unterbrechung arithmetischer Alarm Unterbrechungsbehandlung (UBH) • Beispiele von internen Unterbrechungen Speicherschutzalarm: Prozess greift auf Speicherbereich zu, der nicht vorhanden ist oder auf den er nicht zugreifen darf. Befehlsalarm: dem Operationscode des Maschinenbefehls ist keine Operation zugeordnet. Seitefehltalarm: Seite der virtuellen Adresse ist nicht im Arbeitsspeicher. arithm. Alarm: arithm. Operation kann nicht ausgeführt werden, z.B. Division durch 0. Systemaufruf: kontrollierter Übergang in das Betriebssystem. 4.4.3 Behandlung externer Unterbrechungen Synchrone und asynchrone Unterbrechungen haben hardwaremäßig die Speicherung des aktuellen Prozessorzustandes zur Folge und lösen im Anschluss daran einen indirekten Sprung über eine im Speicher befindliche Sprungtabelle aus. Dabei ordnet der Prozessor jeder synchronen und asynchronen Unterbrechung einen festen Index in der Sprungtabelle zu. An dieser Stelle steht die Anfangsadresse der Unterbrechungsroutine, die entsprechende Folgemaßnahmen einleitet. Falls möglich (Ausnahme ist z.B. ein arithmetischer Alarm) kann die unterbrochene Programmausführung durch die Wiederherstellung des gespeicherten Prozessorzustandes zu einem beliebigen, späteren Zeitpunkt fortgesetzt werden. 63 Schlichter, TU München 4.4. UNTERBRECHUNGSKONZEPT Ablauf • Geräte-Controller meldet Unterbrechung über spezielle Interrupt-Leitung an CPU. • CPU prüft im Befehlszyklus nach jeder Befehlsausführung, ob eine Unterbrechung gemeldet wurde. • Falls Unterbrechung vorliegt: sichern u.a. des aktuellen Befehlszählers, des Programmstatusworts und Sprung zu einer Unterbrechunganfangsbehandlung, die an festgelegter Speicheradresse steht. Routine untersucht Unterbrechungsursache, die vom Controller über Datenleitung gemeldet wird (Unterbrechungsnummer). über Unterbrechungsnummer erfolgt die Auswahl der benötigten Unterbrechungsbehandlungsroutine; Nummer ist i.a. Index in eine Tabelle, dem Unterbrechungsvektor. Vektor enthält Speicheradresse der Unterbrechungsbehandlungsroutine. 4.4.4 Konflikte Konflikte bei Unterbrechungen treten z.B. in folgenden Situationen auf: (1) während einer Unterbrechungsbehandlung treten weitere Unterbrechungen auf; (2) es treffen gleichzeitig mehrere Unterbrechungswünsche ein. • Beispiel E/A-Kanal 1 und E/A-Kanal 2 erledigen beide Aufträge für Prozess A. 64 Schlichter, TU München E/A-Kanal 1 4.4. UNTERBRECHUNGSKONZEPT Prozess A BS-Kern E/A-Kanal 2 externe Unterbrechung Ende E/A Auftrag Unterbrechungsbehandlung (UBH) Konflikt externe Unterbrechung Ende E/A Auftrag • Mögliche Konfliktlösungen – Andere Unterbrechungen nicht zulassen, d.h. Maskierung von Unterbrechungen; anstehende Unterbrechung ignorieren oder vorläufig zurückstellen; Problem: u.a. Rechtzeitigkeit der Unterbrechungsbehandlung. – Interne Unterbrechungen erfolgen stets sofort und geben der zugehörigen Unterbrechungsbehandlung dieselbe Priorität, wie sie der unterbrochene Ablauf hatte. – Externe Unterbrechungen erhalten Prioritäten z.B. (0,...,31) zugeordnet. Die aufgerufene Unterbrechungsbehandlung erhält die Priorität (Ablaufpriorität) der auslösenden Unterbrechung. Eine weitere externe Unterbrechung wird während einer Unterbrechungsbehandlung zugelassen, wenn die Priorität der neuen Unterbrechung höher als die Ablaufpriorität der gerade aktiven Unterbrechungsbehandlung ist. Trifft dieser Fall nicht zu, so wird der Unterbrechungswunsch zurückgestellt, bis ein Ablauf mit einer niedrigeren Ablaufpriorität aktiv wird. • Integration der Unterbrechungsbehandlung in den Befehlszyklus der CPU 65 Schlichter, TU München 4.4. UNTERBRECHUNGSKONZEPT prüfen ob interne Unterbrechung aufgetreten, falls ja, Behandlung der Unterbrechung sonst : prüfen ob externe Unterbrechung mit höherer Priorität. Wenn ja wähle eine mit höchster Priorität. Bei Unterbrechung: sichere alten Zustand, stelle neuen Zustand her und führe ersten Befehl der Unterbrechungsbehandlungsroutine aus. 66 Kapitel 5 Speicherverwaltung Der Adressraum ist eine zentrale Abstraktion, die von der Systemsoftware eines Rechensystems zur Verfügung gestellt werden muss. Über den Adressraum sind alle für die Ausführung eines Anwendungsprogramms notwendigen Operationen und Datenstrukturen zugreifbar. Allgemein wird ein Adressraum durch eine zusammenhängende Menge von Adressen und deren Inhalte definiert. Die maximale Größe eines Adressraums kann aus dem Adressbusaufbau der verwendeten Prozessorarchitektur abgeleitet werden. Modernde Rechensysteme unterscheiden zwischen den Adressräumen der Programme und dem physischen Adressraum (Arbeitsspeicher). 5.1 Fragestellungen Dieser Abschnitt beschäftigt sich mit den Adressräumen für Programme und deren Abbildung auf den physischen Arbeitsspeicher einer Rechenanlage: • Programmadressraum vs. Maschinenadressraum. • Direkte Adressierung, Basisadressierung. • Virtualisierung des Speichers; virtuelle Adressierung, insbesondere Seitenadressierung (nur sehr kurz). 5.2 Einführung Die unmittelbare Nutzung des physischen Adressraums (Arbeitsspeichers) bei der Anwendungsentwicklung ist nicht empfehlenswert. Probleme sind folgende: 67 Schlichter, TU München 5.2. EINFÜHRUNG - Kenntnisse über Struktur und Zusammensetzung des Arbeitsspeichers notwendig. - Kapazitätsengpässe bei der Arbeitsspeichergröße. ⇒ deshalb Programmerstellung unabhängig von realer Speichergröße und eigenschaften. 5.2.1 Adressräume • Maschinenadressraum Der Arbeitsspeicher besteht aus einer Folge von fortlaufend nummerierten Bytes. Die Nummerierung beginnt bei 0. Die Nummer des Bytes bezeichnet man als seine Adresse, genauer als seine physische Speicheradresse oder seine Maschinenadresse. • Programmadressraum Wenn ein Benutzer programmiert, dann benutzt er in seinem Programm Adressen, um seine Variablen zu bezeichnen. Diese Adressen nennen wir Programmadressen. Die Menge der zulässigen Programmadressen ist der Programmadressraum. Dieser ist prozessspezifisch, d.h. Programmadressen haben nur Programmlokale Bedeutung z.B. als Sprungziele. • Speicherabbildung Die CPU muss vor jedem Zugriff auf Befehle und Operanden die jeweiligen Programmadressen in Maschinenadressen umsetzen. Diese Umsetzung wird durch Speicherabbildungen geleistet. Die wichtigsten dieser Abbildungen werden in den folgenden Abschnitten kurz vorgestellt. direkte Adressierung, Basisadressierung, Seitenadressierung 5.2.2 Organisation von Adressräumen Im Adressraum einer Anwendung müssen alle für die Programmausführung notwendigen Daten zur Verfügung gestellt werden. Darunter fallen der Programmco68 Schlichter, TU München 5.2. EINFÜHRUNG de (Text), der Datenbereich (statische und dynamische Daten) und der Laufzeitkeller. Für jede dieser Informationsarten wird ein Bereich im Adressraum spezifiziert, deren Platzierung und Größe durch die Adressraumverwaltung festgelegt wird. • Single-Threaded Adressraum Programm statische Daten dynamische Daten (Halde) Keller niedrige Adresse hohe Adresse • Multi-Threaded Adressraum Programm statische Daten dynamische Daten (Halde) Keller 1 Keller n hohe Adresse niedrige Adresse Für jeden Kontrollfluss (Thread) wird ein eigener Kellerbereich vorgesehen. Der Abstand zwischen den einzelnen Kellern wird meist standardmäßig vom System vorgegeben. Unabhängig von der Anzahl der Laufzeitkeller muss eine Überschneidung zwischen mehreren Kellern oder zwischen dem untersten Keller und der Halde vermieden werden. • Beispiel - Adressräume Moderne Betriebssysteme stellen wenigstens 32 Bit große virtuelle Adressräume für die Anwendungen zur Verfügung, die jeweils in mehrere Bereiche unterteilt sind. Programmcode, statische Daten, Halde und Laufzeitkeller der Anwendung werden jeweils in dem Bereich des Adressraums abgelegt, der der Anwendung zugänglich ist. 69 Schlichter, TU München 5.2. EINFÜHRUNG Windows 32 bit Adressierung Linux 32 bit Adressierung 0 1 GByte 2 GByte 3 GByte 4 GByte spezieller Adressbereich (Größe nicht proportional) 5.2.3 Fragmentierung Unter dem Begriff Fragmentierung versteht man verschiedene Formen der Zerstückelung des noch freien und nutzbaren Teils des Adressraums in kleine Bereiche. Unterscheidung zwischen externer und interner Fragmentierung. • Externe Fragmentierung Es wechseln sich benutzte und unbenutzte Speicherbereiche innerhalb des Adressraums ab. Speicheranforderungen werden jeweils genau erfüllt. 70 Schlichter, TU München 5.2. EINFÜHRUNG Anforderung belegt belegt belegt belegt belegt belegt belegt freie Speicherbereiche • Interne Fragmentierung Der Speicher ist in Bereiche fester Größe untergliedert und Speicheranforderungen werden nur in Vielfachen dieser festen Grundgröße befriedigt. Anforderung freier Speicherbereich 71 Schlichter, TU München 5.2.4 5.3. SPEICHERABBILDUNGEN Forderungen an Adressraumrealisierung Aus der Sicht der Anwendungsprogrammierung können für einen Adressraum eine Reihe wichtiger Forderungen an dessen Realisierung gestellt werden. Hier geht es um den Programmieradressraum für Prozesse, und nicht um den Maschinenadressraum (Arbeitsspeicher). • Homogene und zusammenhängende Adressbereiche. • Größe des genutzten Adressraums unabhängig von der Kapazität des physischen Adressraums (Arbeitsspeichers). • Erkennen fehlerhafter Zugriffe. • Erkennen von Überschneidungen zwischen Halde und Keller sowie zwischen mehreren Laufzeitkellern. • Schutz funktionstüchtiger Anwendungen gegenüber fehlerhaften Anwendungen. Hier geht es darum, dass die Adressbereiche der Anwendungen und auch des Betriebssystems voneinander abgeschottet werden. Ist dieser Schutz nicht gewährleistet, können fehlerhafte Programme den Adressraum einer anderen Anwendung verändern und damit Folgefehler in dieser auslösen ⇒ nicht deterministische Fehler. Fehler dieser Art sind schwer zu reproduzieren und ihre Lokalisierung ist meist extrem schwierig und langwierig. • Kontrollierbares und kontrolliertes Aufteilen der Speicherressourcen auf alle Anwendungen. • Speicherökonomie, minimale Fragmentierung. 5.3 Speicherabbildungen Dieser Abschnitt behandelt einige Mechanismen zur Abbildung von Programmadressen auf Maschinenadressen des Arbeitsspeichers. 5.3.1 Direkte Adressierung Bei der direkten Adressierung werden die Programmadressen direkt als Maschinenadressen interpretiert. Es treten drei Probleme auf: Verschiebbarkeit, Programmgröße, Speicherausnutzung. 72 Schlichter, TU München 5.3. SPEICHERABBILDUNGEN Verschiebbarkeit In einem Mehrprozesssystem sind i.d.R. mehrere Programme im Arbeitsspeicher. Bei direkter Adressierung werden die Programme beim Laden fixiert und müssen dann bis zu ihrem Ende an derselben Stelle bleiben. • Problem Externe Fragmentierung des Arbeitsspeichers. Sei der Arbeitsspeicher zunächst lückenlos mit Programmen P1, P2, P3 gefüllt. P1 P2 P3 Nach Beendigung des Programms P2 entsteht eine Lücke. • Forderung In Mehrprogramme/Mehrprozesssystemen sollten daher Programme verschiebbar sein. Programmgröße Programme können wesentlich größer als der verfügbare Arbeitsspeicher werden. Bei direkter Adressierung muss der Benutzer sein Programm selbst in Segmente zerlegen und diese nach Bedarf selbst nachladen. Man spricht von der sogenannten Overlay-Technik (veraltet). • Forderung Die Programmgröße sollte unabhängig von der realen Arbeitsspeichergröße ist. Speicherausnutzung Programme bestehen aus Modulen, die nur zu bestimmten Zeiten verwendet werden. Beispielsweise wird bei einer Matrizenmultiplikation nur auf die Module, die das Multiplikationsprogramm und auf die Module, die die Daten enthalten, zugegriffen. Es ist nun wünschenswert, von einem Programm nur den Ausschnitt im Arbeitsspeicher zu halten, der momentan und in naher Zukunft benötigt wird. Damit lassen sich mehr Programme im Arbeitsspeicher unterbringen und parallel verarbeiten. Dies steigert den Datendurchsatz des Systems. 73 Schlichter, TU München 5.3. SPEICHERABBILDUNGEN • Forderung Arbeitsspeicher beinhaltet nur die momentan bzw. in naher Zukunft notwendigen Ausschnitte des Programms. Nutzen der Lokalitätseigenschaft von Programmen: durch Datenstrukturen z.B. Arrays, oder Programmstrukturen: Prozeduren, Schleifen. 5.3.2 Basisadressierung Die Basisadressierung hat eine einfache Abbildungsvorschrift: Maschinenadresse = Basisadresse + Programmadresse • Die Basisadresse ist programmspezifisch. • Die Programmadressen aller Programme beginnen jeweils mit Null. Durch die Basisadressierung wird das Problem der Verschiebbarkeit gelöst. Die anderen Probleme bestehen jedoch weiterhin. • Der Arbeitsspeicher besteht aus zwei Klassen: – Belegtbereiche: Speicherbereiche sind Programmen zugeordnet. Verwaltung in Belegtliste. – Freibereiche: Speicherbereiche, die momentan keinem Programm zugeordnet sind, d.h. frei sind. Verwaltung Freibereichsliste. • Speicherverwaltungsstrategien Aufgabe: Finden eines zusammenhängenden Arbeitsspeicherbereichs, der groß genug ist, um das Programm zu speichern. – first-fit Durchsuche die Liste der Freibereiche vom Anfang an und nimm den ersten passenden Frei-Bereich: Spalte nicht benötigten Speicher ab und füge ihn als freien Bereich in die Freibereichsliste ein. – next-fit Durchsuche die Liste der Freibereiche nach first-fit, jedoch beginne die Suche dort, wo man bei der letzten Suche aufgehört hat. 74 Schlichter, TU München 5.3. SPEICHERABBILDUNGEN – best-fit Durchsuche die Liste der Freibereiche vom Anfang an und nimm den passenden Frei-Bereich, der die Speicheranforderungen des Programms am besten erfüllt: Spalte nicht benötigten Speicher ab und füge ihn als freien Bereich in die Freibereichsliste ein. – worst-fit Durchsuche die Liste der Freibereiche vom Anfang an und nimm den FreiBereich, der die Speicheranforderungen des Programms am schlechtesten erfüllt: Spalte nicht benötigten Speicher ab und füge ihn als freien Bereich in die Freibereichsliste ein. – Buddy-Systeme Speicheranforderungen werden in Größen von Zweierpotenzen vergeben, d.h. eine Anforderung wird auf die nächste Zweierpotenz aufgerundet Anforderung 280 Bytes ⇒ Belegung von 512 Bytes = 29 ∗ am Anfang besteht der Arbeitsspeicher aus einem großen Stück. ∗ Speicheranforderung von 2k: ist Speicherbereich dieser Größe vorhanden, dann Unterteilung eines Speicherbereichs der Größe 2k+1 in 2 Speicherbereiche der Größe 2k Bytes. ∗ Freigabe eines Speicherbereichs von 2k: falls auch entsprechendes Partnerstück frei ist, dann Verschmelzung der beiden Speicherbereiche zu einem Speicherstück der Größe 2k+1. 5.3.3 Seitenadressierung Die virtuelle Adressierung wurde Ende der 50er Jahre eingeführt. Ziel ist Virtualisierung des Speichers, Verstecken von realen Beschränkungen, wie Speichergröße, Speicher als sehr großes Feld gleichartiger Speicherzellen zu betrachten. Die Seitenadressierung ("paging") ist die Grundform der virtuellen Adressierung. Ansatz Der Programmadressraum, der sogenannte virtuelle Adressraum eines Prozesses wird in aufeinanderfolgende Seiten (engl. page) gleicher Größe unterteilt. Man spricht deshalb von virtuellen Adressen des Prozesses, anstatt von seinen Programmadressen. 75 Schlichter, TU München 5.3. SPEICHERABBILDUNGEN • Der Maschinenadressraum, also der physische Adressraum des Arbeitsspeichers, wird in Kacheln (engl. frame) unterteilt. Seiten und Kacheln sind i.d.R. gleich groß. • Eigenschaften der Seitenadressierung – Die Seiten eines Prozesses können im Arbeitsspeicher oder auf dem Hintergrundspeicher (Platte) gespeichert sein. – Die Kacheln nehmen die Seiten der Prozesse auf. – Wenn während der Prozessausführung eine virtuelle Adresse des Prozessadressraums verwendet wird, so muss die Seite, in der sich die Adresse befindet, in einer Kachel des Arbeitsspeichers geladen (eingelagert) sein. – Die Zuordnung, welche Seite in welcher Kachel gespeichert ist, und wo sich die Seite auf dem Hintergrundspeicher befindet, erfolgt mittels der SeitenKacheltabelle, die die Seitendeskriptoren enthält. – Seite nicht im Arbeitsspeicher ⇒ Seitenfehler ⇒ Einlagerung der Seite bei Bedarf ("Demand Paging"). – Falls alle Kacheln belegt ⇒ Auslagern einer Seite gemäß einer Seitenersetzungsstrategie. Ziel dieser Strategien ist es, eine möglichst günstige Seite auszuwählen, und diese auf den Hintergrundspeicher auszulagern. Mögliche Strategien: ∗ FIFO (first-in first-out): Verdrängen der ältesten Seite, einfach zu implementieren. ∗ LRU (Least recently used): Verdrängen der am längsten nicht genutzten Seite; wird am häufigsten realisiert, wobei LRU approximiert wird, da eine exakte Realisierung zu aufwendig ist. • virtueller Speicher - Arbeitsspeicher Der Zusammenhang zwischen dem virtuellen Speicher, hier den virtuellen Adressräumen der Prozesse, und dem Arbeitsspeicher sowie Hintergrundspeichermedien wird nachfolgend kurz skizziert. Wir gehen hier vereinfachend davon aus, dass auch die Blöcke als Einheiten des Hintergrundspeichers die Größe einer Seite besitzen. 76 Schlichter, TU München 5.3. SPEICHERABBILDUNGEN virt. Adressraum von P1 Seite 1 von P1 Kachel 1 Seiten-Kachel Tabelle Seite 2 von P1 ... Kachel 2 Auslagern ... ... ..... ... Kachel 3 ... ... ... Seite 1 von P2 Kachel 4 ... Deskriptor Kachel 5 Einlagern Hintergrundspeicher mit Blöcken Seite 2 von P2 ... ..... Arbeitsspeicher mit Kacheln virt. Adressraum von P2 • Vorteile Bei der Seitenadressierung werden durch eine flexible Speicherabbildung alle Probleme der → direkten Adressierung (siehe Seite 72) gelöst. D.h. die Programme können: verschoben werden, größer als der Arbeitsspeicher sein, auch ausschnittsweise im Arbeitsspeicher sein. – Zusätzliche positive Eigenschaften ∗ Es können gemeinsame Speicherbereiche zwischen Prozessen realisiert werden. ∗ Es ist ein differenzierter Zugriffsschutz innerhalb eines Prozesses möglich. 77 Kapitel 6 Prozesskommunikation Disjunkte Prozesse, d.h. Prozesse, die völlig isoliert voneinander ablaufen, stellen eher die Ausnahme dar. Häufig finden Wechselwirkungen zwischen den Prozessen statt ⇒ Prozesse interagieren. Die Unterstützung der Prozessinteraktion stellt einen unverzichtbaren Dienst dar. 6.1 Fragestellungen Dieser Abschnitt beschäftigt sich mit den Mechanismen von Rechensystemen zum Austausch von Informationen zwischen Prozessen. • Kommunikationsarten. • nachrichtenbasierte Kommunikation, insbesondere Client-Server-Modell. • Netzwerkprogrammierung auf der Basis von Ports und Sockets. 6.2 Einführung Prozessinteraktion kann Rechner-lokal und Rechner-übergreifend stattfinden. Prozesse können auf vielfältige Weise Informationen austauschen. 6.2.1 Kommunikationsarten 78 Schlichter, TU München 6.2. EINFÜHRUNG Prozesskommunikation breitbandig implizit explizit asnychron schmalbandig explizit snychron 1:1 1:1 RPC n:1 1:m RMI 1:m n:m n:m Ströme Ereignisse Alarme Signale Die Bandbreite des Kommunikationskanals bestimmt die Datenrate, in der Daten zwischen Prozessen ausgetauscht werden können. Schmalbandige Kanäle Schmalbandige Kanäle werden im Betriebssystem zum Melden von Ereignissen oder für die Synchronisation unterstützt. Übertragung von wenigen Bits an Information, z.B. Setzen von Flags • Dienste des Betriebssystems Melden von Ereignissen, Warten auf Ereignisse, Ereignisverwaltung. • Beim Ablauf von Prozessen können Alarme entstehen (z.B. arithmetische Alarme). • Die Alarme werden über Namen identifiziert, die im BS vereinbart sind. Das BS stellt Dienste zur Zustellung von Alarmen zur Verfügung. Implizite Kommunikation Implizite Kommunikation ist eine breitbandige Kommunikationsform. Die Kommunikation erfolgt über einen gemeinsamen Speicher (Dateien, Register, Datenstrukturen). 79 Schlichter, TU München 6.2. EINFÜHRUNG • Die Kommunikation findet ohne direkte Unterstützung und ohne Kenntnis des BS statt. • Vorteil: einfach und schnell (kein Kopieren zwischen Adressräumen). • Nachteil: a) gemeinsame Bereiche sind nicht immer vorhanden: z.B. in physisch verteilten, vernetzten Systemen gibt es i.d.R. keinen gemeinsamen Speicher. b) gegebenenfalls aufwendiges busy waiting ⇒ Mischform: Ereigniszustellung, d.h. schmalbandige Kommunikation, die das Vorhandensein von Daten signalisiert. • Implizite Kommunikationsformen Verschiedene Formen der impliziten Kommunikation 1:1 ein Puffer pro Sender/Empfänger-Paar n:1 n Sender senden Nachrichten an einen Empfänger, z.B. Sender: Prozesse senden Druckaufträge Empfänger: Drucker-Server 1:m Mitteilung an alle Prozesse (Broadcast, Multicast); Broadcast: z.B. Erfragen, wo ein spezieller Dienst angeboten wird; Shutdown Message an alle Rechner. Multicast: z.B. Nachricht an Gruppe gleichartiger Server. n:m n Erzeuger schreiben in Puffer und m Verbraucher lesen aus Puffer. 80 Schlichter, TU München S1 6.2. EINFÜHRUNG S1 Sn prozessspezifischer oder zentraler Puffer prozessspezifischer oder zentraler Puffer E1 E1 1:1 Kommunikation S1 Briefkasten (mail box) E1 n:1 Kommunikation Sn Em n:m Kommunikation Si i-ter Senderprozess Ei i-ter Empfängerprozess Explizite Kommunikation Diese Kommunikationsart wird realisiert durch den Austausch von Nachrichten ("message passing") ⇒ nachrichtenbasierte Kommunikation. Die Nachrichtenkommunikation ist immer dann die geeignete Kommunikationsform, wenn die beteiligten Prozesse in disjunkten Adressräumen liegen, und damit keine Möglichkeit haben, auf einen gemeinsamen Speicher zuzugreifen. • Betriebssystem enthält einen Nachrichtendienst ND (das Kommunikationssystem), der den Austausch der Nachrichten zwischen Prozessen realisiert. ND unterstützt 2 Systemdienste: send (E: process, m: message) receive (S: process, m: message) Mittels send wird eine Nachricht m für den Empfänger E an den Nachrichtendienst ND übergeben. Mit receive entnimmt ein Empfänger E die Nachricht m, die vom Sender S gesandt wurde, von ND. Der Absender wird gewöhnlich in der Nachricht m codiert. • prinzipieller Ablauf 81 Schlichter, TU München Sende prozess S Nachricht m send 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Nachrichten dienst ND Nachricht m Empfänger prozess E receive Falls die Prozesse auf unterschiedlichen Rechnern sind, sind die Nachrichtendienste der beteiligten Betriebssysteme involviert. In diesem Fall findet eine Kommunikation zwischen den beiden Nachrichtendiensten statt. • Aufbau einer Nachricht Eine Nachricht besteht aus 2 grundlegenden Komponenten: Nachrichtenkopf: Verkehrsinformation, Empfängeridentifikation Nachrichteninhalt: Nutzlast (payload) z.B. Sender- und • explizite Kommunikation ist besonders geeignet in verteilten, vernetzten Systemen. 6.3 Nachrichtenbasierte Kommunikation Bei nachrichtenbasierter Prozessinteraktion tauschen Prozesse gezielt Informationen durch Verschicken und Empfangen von Nachrichten aus; ein Kommunikationssystem unterstützt an der Schnittstelle wenigstens die Funktionen send und receive. Nachrichtenkommunikation ist die natürliche Form der Prozessinteraktion in Rechnernetzen. Prozesse, die auf verschiedenen Rechnerknoten platziert sind, müssen ein physisches Übertragungssystem benutzen, um miteinander in Kontakt zu treten. 6.3.1 Elementare Kommunikationsmodelle Klassifikationsschema für die Nachrichtenkommunikation anhand von 2 Dimensionen: generelles Muster der Nachrichtenkommunikation. zeitliche Kopplung der beteiligten Prozesse. Klassifikationsschema • Elementare Kommunikationsmuster sind Meldung ("signal") und Auftrag ("request"). 82 Schlichter, TU München 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Meldung: Einweg Nachricht vom Sender zum Empfänger (unidirektional). Auftrag: Zweiweg Nachricht zwischen Sender und Empfänger (bidirektional). Sie beginnt mit dem Versenden eines Auftrags an den Empfänger und endet mit der Übergabe einer Erfolgsbestätigung über den durchgeführten Auftrag an den Sender. • Synchronität definiert den Kopplungsgrad zwischen Prozessen bei der Durchführung einer Nachrichtentransaktion: asynchron: Entkopplung des Senders und Empfängers. synchron: beide synchronisiert. Prozesse werden zur Nachrichtenübertragung Meldung • Asynchrone Meldung Sender wird lediglich bis zur Ablieferung der Meldung an das Nachrichtensystem (Kommunikationssystem) blockiert. 83 Schlichter, TU München Sender S 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Nachrichtendienst ND Empfänger E send Meldung receive Zeit – Nachrichtendienst des Betriebssystems puffert Nachricht; Sender S kann seine Ausführung fortsetzen, sobald Nachricht N in den Nachrichtenpuffer des ND eingetragen ist. S wartet nicht, bis E die Nachricht empfangen hat. – Empfänger E zeigt durch receive an, dass er am Empfang der Nachricht N interessiert ist. Empfänger wird blockiert, bis Sender Nachricht bereit stellt. • Synchrone Meldung Sender und Empfänger von Meldungen sind zeitlich gekoppelt. Sender S send Nachrichtendienst ND Empfänger E Meldung receive Quittung Zeit 84 Schlichter, TU München 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Über die Ablieferung der Nachricht wird der Sender durch eine Quittungsnachricht informiert, die zur Aufhebung der Blockade des Senders führt. – Rendezvous-Technik: Sender und Empfänger stellen vor Austausch der eigentlichen Meldung die Sende- und Empfangsbereitschaft her. Auftrag • Synchroner Auftrag Bearbeitung der Nachricht durch Empfänger und Senden der Resultatnachricht sind Teil der Nachrichtentransaktion. Sender S send Nachrichtendienst ND Auftrag Empfänger E receive Auftrags bearbeitung Resultat reply Zeit Synchrone Aufträge schränken die Parallelarbeit zwischen Sender und Empfänger noch stärker ein als synchrone Meldungen, da die zeitliche Kopplung auch die Bearbeitung der Nachricht umfasst. Diese Kommunikationsform wird gerade im Zusammenhang mit dem Client-Server Modell sehr oft verwendet. • Asynchroner Auftrag Auftrag und Resultat werden als Paar unabhängiger Meldungen verschickt. 85 Schlichter, TU München Sender S 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Nachrichtendienst ND send Empfänger E Auftrag receive Auftrags bearbeitung receive result Resultat reply Zeit Vorteile/Nachteile asynchrones Senden • Vorteile asynchrones Senden – nützlich für Realzeitanwendungen. – ermöglicht parallele Abarbeitung durch Sender und Empfänger. – anwendbar zum Signalisieren von Ereignissen. • Nachteile asynchrones Senden – Verwaltung des Nachrichtenpuffers durch BS erforderlich. – Benachrichtigung des Senders S im Fehlerfall und Behandlung von Fehlern ist problematisch. – Entwurf und Nachweis der Korrektheit des Systems ist schwierig. 6.3.2 Erzeuger-Verbraucher Problem Auf der Basis der nachrichtenbasierten Kommunikation wird das ErzeugerVerbraucher Problem mit Hilfe von send und receive Operationen realisiert. 86 Schlichter, TU München 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Erzeuger S: while (true) { produziere Dateneinheit; send (E, Dateneinheit); } Verbraucher E: while (true) { receive (S, Dateneinheit); verbrauche Dateneinheit; } Es existiert kein gemeinsamer Speicherbereich, der bzgl. der Zugriffe von Erzeuger und Verbraucher synchroniert werden muss. Die Synchronisation von Erzeuger und Verbraucher erfolgt durch das Kommunikationssystem selbst. 6.3.3 Modellierung durch ein Petrinetz Petri-Netze dienen häufig zur Modellierung von Kommunikationsabläufen, sogenannten Kommunikationsprotokollen. Sie ermöglichen die Analyse der Protokolle, z.B. Erkennung von Verklemmungen. Modellierung einer synchronen Kommunikation: Sendebereit send message Prozess 1 receive message buffer full wait for ack. Prozess 2 message received receive ack. send ack. buffer full ack. received ack. sent 87 Schlichter, TU München 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Problem: unendliches Warten Pragmatische Lösung mit Hilfe von Timeouts • Sender bzw. Empfänger warten nur eine festgelegte Zeit, Sender: falls kein Acknowledgement (Quittung) eintrifft, z.B. erneutes Senden. • Probleme dabei? u.a. Duplikate müssen vom Empfänger erkannt werden; gesendete Nachrichten kommen zu spät an, sind veraltet etc. 6.3.4 Ports Bisher bestand zwischen Sender und Empfänger eine feste Beziehung, die über Prozessidentifikatoren (z.B. Namen oder Nummer) hergestellt wurde. Nachteile Prozessnummern ändern sich mit jedem Neustart. Prozessnamen sind nicht eindeutig, z.B. falls Programm mehrmals gestartet wurde. ⇒ Deshalb Senden von Nachrichten an Ports. Sie stellen Endpunkte einer Kommunikation dar. Sie können bei Bedarf dynamisch eingerichtet und gelöscht werden. Dazu existieren folgende Funktionen: portID = createPort(); deletePort(portID); send(E.portID, message); receive(portID, message); • ein Port ist mit dem Adressraum des zugehörigen Prozesses verbunden. • der Empfängerprozess kann sender-spezifische Ports einrichten. • ein Rechner mit einer IP-Adresse unterstützt mehrere tausend Ports. • der Name des Ports ist für einen Rechner eindeutig. • die Portnummern 1 - 1023 sind fest reserviert für bestimmte Protokolle (bzw. deren Applikationen). • Übersicht: fest zugeordnete Ports 88 Schlichter, TU München Protokoll FTP Telnet Port 21 23 SMTP time finger HTTP POP3 25 37 79 80 110 RMI 1099 6.3.5 6.3. NACHRICHTENBASIERTE KOMMUNIKATION Beschreibung Kommandos für Dateitransfer (get, put) interaktive Terminal-Sitzung mit entferntem Rechner Senden von Email zwischen Rechnern Time-Server liefert aktuelle Zeit liefert Informationen über einen Benutzer Protokoll des World Wide Web Zugang zu Email durch einen sporadisch verbundenen Client Zugang zum Registrieren von entfernten Java Objekten. Kanäle Bisher wurde von einer verbindungslosen Kommunikation ausgegangen, d.h. eine Nachricht kann an einen Port geschickt werden. Bei einer verbindungsorientierten Kommunikation muss zuerst eine logische Verbindung zwischen den Kommunikationspartner eingerichtet werden ⇒ Kanal ("socket"). • Einrichtung eines Kanals zwischen Ports, d.h. Verknüpfen zweier Ports. • bidirektionale Übertragung über Kanäle. • Die Sende- bzw. Empfangsoperation bezieht sich auf die lokale PortID; send(local portID, message); receive(local portID, message); • TCP/IP unterstützt verbindungsorientierte Kommunikation. 6.3.6 Ströme Ströme (engl. streams) sind eine Abstraktion von Kanälen. Sie verdecken die tatsächlichen Nachrichtengrenzen. Ein Sender schickt mittels send-Operationen Nachrichten an den Empfänger. Die Nachrichten werden jedoch logisch zu einem Bytestrom vereinigt, dem man auf Empfangsseite die Nachrichtengrenzen nicht mehr entnehmen kann. Der Empfänger kann den Bytestrom in Portionen verarbeiten, ohne sich an den ursprünglichen Nachrichtengrenzen zu orientieren. 89 Schlichter, TU München Sender 6.4. CLIENT-SERVER-MODELL send (120 Bytes) send (74 Bytes) send (233 Bytes) Strom 1 Byte receive (50 Bytes) receive (377 Bytes) Empfänger • BS-Dienste: Verbindungsauf- und -abbau, schreiben in Strom, lesen aus Strom. • Dienste für Dateizugriffe oder Zugriffe auf Geräte: spezielle Ausprägung der stromorientierten Kommunikation. • I/O in Java basiert auf Ströme. Klasse java.io.OutputStream zum Schreiben von Daten Klasse java.io.InputStream zum Lesen von Daten Spezialisierungen z.B. durch FileOutputStream, BufferedOutputStream oder FileInputStream. 6.4 Client-Server-Modell Client-Server Modell basiert i.a. auf der Kommunikationsklasse der synchronen Aufträge. Server stellen Dienste zur Verfügung, die von vorher unbekannten Clients in Anspruch genommen werden können. • Client-Server Architektur 90 Schlichter, TU München 6.4. CLIENT-SERVER-MODELL Client C Server S Auftrag blockiert Ausführung Resultat Zeit • Definitionen – Definition: Client Ein Client ist eine Anwendung, die auf einer Clientmaschine läuft und i.a. einen Auftrag initiiert, und die den geforderten Dienst von einem Server erhält. Clients sind meist a-priori nicht bekannt. Clients sind oft Benutzerprozesse, die dynamisch erzeugt und gelöscht werden. – Definition: Server Ein Server ist ein Subsystem, das auf einer Servermaschine läuft und einen bestimmten Dienst für a-priori unbekannte Clients zur Verfügung stellt. – Server sind dedizierte Prozesse, die kontinuierlich folgende Schleife abarbeiten. while (true) { receive (empfangsport, auftrag); führe Auftrag aus und erzeuge Antwortnachricht; bestimme sendeport für Antwortnachricht; send (sendeport, resultat); } – Client und Server kommunizieren über Nachrichten, wobei beide Systeme auf unterschiedlichen Rechnern ablaufen können und über ein Netz miteinander verbunden sind. • Beispiele für Dienste (Services), die mittels Server realisiert werden: Dateidienst, Zeitdienst, Namensdienst. 91 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG • Multi-Tier ein System kann sowohl Client als auch Server sein. Server Client Server Client – Beispiel Web Browser (Applets) HTTP cgi Web Server Anwendungs Server SQL Daten bank 6.5 Netzwerkprogrammierung Bedingt durch rasche Verbreitung des Internet hat auch das Interesse an NetzAnwendungen sehr zugenommen. Netz-Anwendungen sind verteilte Anwendungen, die jeweils aus mehreren Teilkomponenten bestehen und die im Netz verteilt auf verschiedenen Rechensystemen ausgeführt werden. Teilkomponenten sind hier nicht einzelne Objekte, sondern komplexe Verarbeitungseinheiten (z.B. ein Modul bestehend aus einer Menge von Objekten). Eine verteilte Anwendung ist eine Anwendung A, dessen Funktionalität in eine Menge von kooperierenden Teilkomponenten A1, .., An, n ∈ IN, n > 1 zerlegt ist; 92 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG Jede Teilkomponente umfasst Daten (interner Zustand) und Operationen, die auf den internen Zustand angewendet werden. Teilkomponenten Ai sind autonome Prozesse, die auf verschiedenen Rechensystemen ausgeführt werden können. Mehrere Teilkomponenten können demselben Rechensystem zugeordnet werden. Teilkomponenten Ai tauschen über das Netz untereinander Informationen aus. Die Teilkomponenten können z.B. auf der Basis des Client-Server Modells realisiert werden. 6.5.1 Einführung In Berkeley Unix wurde das Konzept von Sockets eingeführt, um die Netzwerkprogrammierung zu erleichtern. Sie erlauben jede Netzverbindung als einen Strom von Bytes zu betrachten, die gelesen bzw. geschrieben werden können. Ein Socket definiert einen einfachen, bidirektionalen Kommunikationskanal zwischen 2 Rechensystemen, mit Hilfe dessen 2 Prozesse über ein Netz miteinander kommunizieren können. Input Strom Client Server Output Strom Socket Verbindung Socket Grundlagen Sockets abstrahieren von den technischen Details eines Netzes, z.B. Übertragungsmedium, Paketgröße, Paketwiederholung bei Fehlern, Netzadressen. Anfänglich standen Sockets nur in Unix Umgebungen zur Verfügung. In der Zwischenzeit werden sie auch von Windows, dem MacOs und von Java unterstützt. • Ein Socket kombiniert 2 Ströme, einen Input- und einen Output-Strom. 93 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG • Ein Socket unterstützt die folgenden Basisoperationen: richte Verbindung zu entferntem Rechner ein ("connect"). sende Daten. empfange Daten. schließe Verbindung. assoziiere Socket mit einem Port. warte auf eintreffende Daten ("listen"). akzeptiere Verbindungswünsche von entfernten Rechnern (bzgl. assoziiertem Port). 6.5.2 Server Protokoll Ein Server kommuniziert mit einer Menge von Clients, die a priori nicht bekannt sind. Ein Server benötigt eine Komponente (z.B. ein Verteiler-Thread), die auf eintreffende Verbindungswünsche reagiert. • Informeller Ablauf aus Serversicht 1. Erzeugen eines SocketServer und Binden an einen bestimmten Port. Ein Port entspricht einer FIFO Warteschlange. Sie sammelt die Verbindungswünsche der Clients. Die maximale Länge ist abhängig vom Betriebssystem, z.B. 50. Falls die Warteschlange voll ist, werden keine weiteren Verbindungswünsche akzeptiert. 2. Warten auf Verbindungswünsche von Clients. Falls der Client bzgl. einer Socketverbindung autorisiert ist, akzeptiert der Server den Verbindungswunsch. Der Server wird blockiert, bis die accept-Methode des Servers die Verbindung zwischen Client und Server eingerichtet hat. Die beiden Ströme der Socketverbindung werden eingerichtet. 3. Austausch von Daten zwischen Client und Server entsprechend einem wohldefinierten Protokoll (z.B. HTTP). 4. Schließen einer Verbindung (durch Server, durch Client oder durch beide); weiter bei Schritt 2. • Programmstück 94 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG Socket socket; //reference to socket ServerSocket port; //the port the server listens to try { port = new ServerSocket(10001, ...); socket = port.accept(); //wait for client call // communicate with client socket.close() } catch (IOException e) {e.printStackTrace();} • Für das Abhören des Ports kann ein eigener Verteiler-Thread spezifiziert werden; die Bearbeitung übernehmen sogenannte Worker-Threads. 6.5.3 Client Protokoll Der Client initiiert eine Socket-Verbindung durch Senden eines Verbindungswunsches an den Port des Servers. Informeller Ablauf aus Clientsicht 1. Erzeugen einer Socket Verbindung. 2. Austausch von Daten zwischen Client und Server über die Duplex-Verbindung entsprechend einem wohldefinierten Protokoll (z.B. HTTP). 3. Schließen einer Verbindung (durch Server, durch Client oder durch beide). Programmstück Socket connection; //reference to socket try { connection = new Socket("www11.in.tum.de", 10001); ........ // communicate with client connection.close() } catch (IOException e) {e.printStackTrace();} 6.5.4 Bidirektionale Stromverbindung Sockets bestehen aus 2 Strömen für die Duplexverbindung zwischen Client und Server. Diese beiden Ströme werden automatisch beim Einrichten einer 95 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG Socket-Verbindung erzeugt. Durch die Verwendung von Strömen kann dieselbe Programmiermethode verwendet wie bei I/O, Dateizugriff, etc. • Schreiben auf Socket void writeToSocket(Socket sock, String str) throws IOException { oStream = sock.getOutputStream(); for (int k = 0; k < str.length(); k++) oStream.write(str.charAt(k)); } • Lesen von Socket String readFromSocket(Socket sock) throws IOException { iStream = sock.getInputStream(); String str = ""; char c; while ( (c = (char) iStream.read()) != ’\n’) str = str + c; return str; } 6.5.5 Java Socket Class Java unterstützt die beiden grundlegenden Klassen: java.net.Socket zur Realisierung der Client-Seite einer Socket. java.net.ServerSocket zur Realisierung der Server-Seite einer Socket. Client-Seite einer Socket • Constructor public Socket(String host, int port) throws UnknownHostException, IOException Der Parameter host ist ein Rechnername, z.B. www11.in.tum.de. Falls der Domain Name Server den Parameter host nicht auflösen kann, wird die Exception UnknownHostException ausgelöst. Falls die Socket aus einem anderen Grund nicht geöffnet werden kann, wird IOException ausgelöst, z.B. 96 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG der entfernte Host akzeptiert keine Verbindungen. Es gibt noch eine Reihe anderer Konstruktoren, z.B. public Socket(InetAddress host, int port) throws IOException Das Objekt der Klasse InetAddress umfasst den Rechnernamen und seine IPAdresse, d.h. eine Auflösung durch den Domain Name Server ist nicht mehr notwendig. • Information über eine Socket public InetAddress getInetAddress(); liefert als Ergebnis den Namen und IP-Adresse des entfernten Rechners, zu dem die Socket-Verbindung existiert. public int getPort(); liefert als Ergebnis die Nummer des Ports, mit dem die Socket-Verbindung am entfernten Rechner assoziiert ist. public int getLocalPort(); liefert als Ergebnis die Nummer des Ports, mit dem die Socket-Verbindung am lokalen Rechner assoziiert ist. • Ein-/Ausgabe public InputStream getInputStream() throws IOException; liefert den InputStream, von dem Daten gelesen werden können. Er unterstützt die Methode read zum Lesen der Daten. InputStream ist ein Basis-Strom, der mit Hilfe von SubClassing spezialisiert werden kann. public OutputStream getOutputStream() throws IOException; liefert den OutputStream, in dem Daten geschrieben werden können. Er unterstützt die Methode write zum Schreiben der Daten. OutputStream ist ein Basis-Strom, der mit Hilfe von SubClassing spezialisiert werden kann. Server-Seite einer Socket • Constructor public ServerSocket(int port) throws IOException, BindException erzeugt eine Socket auf Server-Seite und assoziiert sie mit dem Port. 97 Schlichter, TU München 6.5. NETZWERKPROGRAMMIERUNG • Einrichten/Schließen einer Verbindung public Socket accept() throws IOException diese Methode blockiert und wartet auf Verbindungswünsche von Clients. public void close() throws IOException • Ein-/Ausgabe public InputStream getInputStream() throws IOException; liefert den InputStream, von dem Daten gelesen werden können. public OutputStream getOutputStream() throws IOException; liefert den OutputStream, in dem Daten geschrieben werden können. 98 Kapitel 7 Zusammenfassung Dieser Vorlesungsteil beschäftigte sich mit Aspekten des Betriebssystems und der systemnahen Programmierung. Insbesondere wurden folgende Aspekte behandelt: • ein allgemeiner Überblick über Betriebssysteme, Betriebssystemarchitekturen. • Synchronisation von Prozessen beim Zugriff auf gemeinsame Ressourcen. • Verwaltung von Prozessen und deren Zuteilung an die CPU, um sie auszuführen. • einfache Verwaltung des Arbeitsspeichers aus der Sicht des Betriebssystems. • Prozesskommunikation in lokalen und verteilten Systemen. 99