Vorlesung Betriebssysteme I Organisatorisches
Transcription
Vorlesung Betriebssysteme I Organisatorisches
Vorlesung Betriebssysteme I Thema 1: Einführung Robert Baumgartl 12. Oktober 2015 1 / 34 Organisatorisches I 2/0/2, d. h., 90’ Vorlesung und 90’ Praktikum pro Woche I Vorlesung dienstags 15:10 Uhr, Z 211 I Lehrender: Prof. Robert Baumgartl Kontakt: I I I I I I Praktikum in Linux-Laboren (Z 136c/Z 146a) I I I [email protected] dem Subject bitte „[BS1]“ voranstellen Tel. 462 2510 Raum Z 357 Betreuung durch mich und Laboringenieure (Herr Schubert, Herr Paul) Start: 12. 10. 2015 Prüfung: Klausur, 90’, Voraussetzung: Beleg 2 / 34 Vorkenntnisse Bitte um Handzeichen – Wer hat schon I mit Windows gearbeitet? I mit Linux (o. a. Unix) gearbeitet? I einen der Editoren vi oder emacs genutzt? I in C programmiert? I make eingesetzt? I fork() beim Programmieren benutzt? I in der Open-Source-Community mitgewirkt? I einen Treiber geschrieben? 3 / 34 Vorkenntnisse II Wer weiß, was das macht: char *foo(char *dest, const char *src) { while(*dest++ = *src++); } . . . und das? bash$ :(){ :|:&};: (Vorsicht! Nicht ausprobieren!) 4 / 34 Wozu befassen wir uns mit Betriebssystemen? ... es gibt doch Windows! Einige Gedanken: I Grundlagenfach der Informatik I BS gehören zu den komplexesten Softwaresystemen überhaupt! aktiver Forschungsgegenstand I I I I I Betriebssysteme-Sicherheit Skalierbarkeit Sensornetze Echtzeitbetriebssysteme I Linux! I und zuguterletzt: Wir wollen doch kompetent die Frage beantworten, ob Linux oder Windows besser ist?! 5 / 34 Vorläufige Themenübersicht 1. Einführung 2. Linux in a Nutshell 3. Dateisystem 4. Grundlegende Begriffe, Teil 2 5. Aktivitäten 6. Kommunikation 7. Scheduling 8. Threads (Aktivitäten, die zweite) 9. Synchronisation 7 / 34 Einige Aspekte von Betriebssystemen I Bedienung I Administration I Programmierung für Betriebssysteme I Programmierung von Betriebssystemen I Abstraktionen für Aktivitäten (Prozesse, Threads, Coroutinen, Fibers, Tasks) I Fehlertoleranz I Security & Safety I Forensik 8 / 34 Ziel des Kurses Vermittlung von vorwiegend praktischen Kenntnissen zu I Nutzung elementarer Werkzeuge I Automatisierung von Bedienhandlungen I Interaktion zwischen Applikationen und Betriebssystem(en) I Struktur und Vorgängen innerhalb von Betriebssystemen I Unix-artigen und Windows-Betriebssystemen 9 / 34 Eine kurze Geschichte der . . . Betriebssysteme Andrew Tanenbaum unterscheidet 4 Epochen 1. 1945-55 – Elektronenröhren I keine Betriebssysteme 2. 1955-65 – Transistoren I I Mainframes – kommerzielle Computer Batchsysteme (Ziel: maximale Rechnerauslastung) 3. 1965-75 – niedrig integrierte Schaltkreise I I I I I I I IBM System/360 → OS/360 (Ziel: Kompatibilität) Multiprogramming (mehrere Ausführungseinheiten gleichzeitig) Spooling Timesharing (Ziel: Reduktion der Systemantwortzeit) MULTICS (ambitioniert, aber erfolglos) Minicomputer (kleiner als Mainframe; DEC PDP-1. . . -11) UNIX (portabel, offen, kollaborativ entwickelt) 10 / 34 Eine kurze Geschichte der . . . Betriebssysteme Andrew Tanenbaum unterscheidet 4 Epochen 4. 1975-heute — hoch integrierte Schaltkreise I I I I I I I 1976: Prozessor Zilog Z80 → CP/M etwa ab 1977: Homecomputer (Apple II, C64, . . . ) 1979: Prozessor i8088; PC 1980: QDOS → MS-DOS 1984: Apple Macintosh → MacOS (GUI) 1985: Microsoft Windows 1.0 1992: Linux 11 / 34 Plattformen fürs „Personal Computing“ I verkaufte „Personal Computing Units“ pro Jahr I Quelle: http://twitpic.com/87nbjj 12 / 34 GUI von MacOS (1984) (http://upload.wikimedia.org/wikipedia/en/5/50/Apple_Macintosh_Desktop.png) 13 / 34 Betriebssysteme Es gibt: I I I Windows-Familie (2.0 → 10) Linux MacOS X ... das wars, oder? I MS-DOS, RTEMS, QNX, FreeBSD, SymbianOS, PalmOS, RTAI, HP-UX, BeOS, Minix, Chorus, L4, Mach, Amoeba, OS/390, DCP, TOS, CP/M, VMS, eCos, Contiki, OS/2 . . . I vgl. http://de.wikipedia.org/wiki/Liste_der_Betriebssysteme 14 / 34 Betriebssysteme Es gibt: I I I Windows-Familie (2.0 → 10) Linux MacOS X ... das wars, oder? I MS-DOS, RTEMS, QNX, FreeBSD, SymbianOS, PalmOS, RTAI, HP-UX, BeOS, Minix, Chorus, L4, Mach, Amoeba, OS/390, DCP, TOS, CP/M, VMS, eCos, Contiki, OS/2 . . . I vgl. http://de.wikipedia.org/wiki/Liste_der_Betriebssysteme 15 / 34 UNIX I . . . ist kein Betriebssystem, sondern eine ganze Familie I Name ist ein Wortspiel aus dem Vorgänger „Multics“ und „unique“ I zusammen mit der Programmiersprache C in den 70er Jahren entwickelt I einige Vertreter: *BSD, System V, Linux, HP-UX, AIX, Solaris, Minix I sogar Microsoft hat ein UNIX entwickelt: XENIX (es ist aber schon lange tot) I der zugehörige Standard heißt POSIX I beliebt vor allem im Serverbereich (aber nicht nur!) I Nutzer haben mit Vorurteilen zu kämpfen . . . 16 / 34 Lizensierungsaspekte 2 grundlegende Ideen: I Closed Source: Quellcode ist geheim, „Betriebsgeheimnis“, steht i. a. nur dem Hersteller zur Verfügung I Open Source: Quellcode steht prinzipiell jedem zur Verfügung → kann modifiziert und weiterverteilt werden (und soll dazu ermuntern) 18 / 34 Kommerzielle Lizenzen I kann (muss aber nicht) Einblick in Quellcode umfassen (z. B. für nichtkommerzielle Zwecke) I erfordert meist Vertrag („End User License Agreement“ (EULA)) I typische EULAs sind im EU-Raum jedoch unwirksam (zum Glück) Kosten für: I Entwicklungswerkzeuge I Bibliotheken (z. B. für Protokollstacks oder zum Debugging) I Royalties: pro Installation auf Zielgerät I (Schulung der Entwickler) 19 / 34 GNU General Public License (GPL) I I Richard Stallman, 1989 Kurzform: 1. Das Werk darf für beliebige Zwecke verwendet werden (auch kommerziell). 2. Das Werk darf beliebig weitergegeben werden, kostenlos oder kostenpflichtig. Der Quelltext (auch eigener Modifikationen) ist mitzuliefern. 3. Das Werk darf beliebig modifiziert werden. 4. Es dürfen keine Einschränkungen an diesen Regeln erfolgen. I enthält sog. starkes „Copyleft“: erzwingt die Weiterverbreitung von aus freien Werken abgeleiteten Werken → niemand kann die Verbreitung eines ursprünglich freies Werk verhindern („Virulenz“) I wichtigste Open-Source-Lizenz I Beispiele: Linux, eCos, GCC, emacs, vi 20 / 34 Nachteile der GPL I untersagt das Vermischen von GPL-Code mit Code, der unter inkompatibler Lizenz steht (also alle closed source, aber auch freie Software) I → Binärtreiber bestimmter Grafikkarten sind eigentlich illegal im Linux-Kern (geduldet; „tainted kernel“) I erschwert die Migration zu freier Software, da in Unternehmen existierende kommerzielle Software nicht ohne weiteres in diese integriert werden kann I Verletzungen werden verfolgt! (gpl-violations.org) 21 / 34 Wozu benötigen wir nun ein Betriebssystem? 1. Bereitstellen von Diensten und dafür notwendigen Abstraktionen (z. B. „Prozess“, „Datei“, „Gerätetreiber“ u. v. a. m.) 2. Ressourcenverwaltung inklusive Protokollierung 3. Koordinierung paralleler Abläufe 4. Basis für Schutz und Sicherheit 22 / 34 Klassifizierung von Betriebssystemen Kriterium: Nutzeranzahl I Single-User-BS I Multi-User-BS Kriterium: Anzahl unabhängiger Aktivitäten I Single-Tasking-BS I Multi-Tasking-BS Kriterium: Kommunikation mit der Umwelt I BS zur Stapelverarbeitung (Batchbetrieb) I interaktives BS I BS für autonome Systeme 23 / 34 Klassifizierung von Betriebssystemen II Kriterium: Verteilung I lokales BS I verteiltes BS Kriterium: Zielarchitektur/Einsatzzweck I Serverbetriebssystem I eingebettetes Betriebssystem I Echtzeitsystem I Mainframe-BS I BS für Personal Computer I BS für Smart Card I BS zur Ausbildung/Lehre 24 / 34 Apropos: welches Betriebssystem wird eingebettet eingesetzt? Quelle: http://www.eetimes.com/document.asp?doc_id=1263083 25 / 34 Interaktion mit dem Betriebssystem Paradigmen: I vorwiegend textorientiert (Konsole, Shell, Eingabeaufforderung) I grafische Oberfläche (Windows, KDE, Windowmaker) Die Frage Was ist besser? führt unausweichlich zu Ärger I keine Frage des Betriebssystems sondern der persönlichen Vorliebe 26 / 34 Modellierung und Strukturierung von BS Problem: BS gehören zu den komplexesten Softwaresystemen überhaupt! → durch Lesen des Programmcodes kaum zu verstehen Technik: Durch Reduktion der möglichen Kommunikationsbeziehungen zwischen Komponenten Übersicht schaffen. 27 / 34 Modell 1: Monolithisches System I Andrew Tanenbaum: “The Big Mess” I jede Routine, Funktion, . . . darf jede andere im System rufen unübersehbare Vielfalt potentieller Kommunikationsbeziehungen I kein Information Hiding I BS = Sammlung von Funktionen I typisch für „historisch gewachsene“ Systeme I effizient! 28 / 34 Modell 2: Geschichtetes System I Applikation Steuerungshierarchie I Kommunikation nur zwischen Instanzen benachbarter Schichten Beispiel: OSI-Schichtenmodell der ISO für Kommunikationsprotokolle (7 Schichten) leider kein vergleichbarer Standard in der BS-Technologie etabliert Diensthierarchie I Dateisystem Gerätetreiber Betriebssystem−Kern Hardware Abbildung: Beispiel für ein geschichtetes System I Gefahr der Ineffizienz 29 / 34 Variante: quasikonsistente Schichtung I Schichtung nicht zwingend: Applikation COMMAND DOS BIOS I/O CPU Applikationen "Betriebssystem" Hardware Abbildung: Quasikonsistente Schichtung im MS-DOS 30 / 34 Beispiel für ein komplex geschichtetes Modell Windows, and Chapter 4 details management mechanisms such as the registry, service processes, and Windows Management Instrumentation. Other chapters explore in even more detail the internal structure and operation of key areas such as processes and threads, memory management, security, the I/O manager, storage management, the cache manager, the Windows file system (NTFS), and networking. Mark Russinovitch et al: Windows Internals. 6th ed., Microsoft Press, 2012, S. 47 System Processes Session manager Local session manager Services Service control Windows DLLs manager Applications Service host Windows DLLs Windows DLLs Windows DLLs Print spoolerDLLs Windows Local Security Windows AuthorityDLLs Winlogon Windows DLLs Windows User application SUA Subsystem DLLs Windows DLLs Wininit Windows DLLs Environment Subsystems Windows DLLs Windows DLLs NTDLL.DLL User mode Kernel mode System threads System Service Dispatcher (Kernel mode callable interfaces) Advanced local procedure call Configuration manager Process manager Memory manager Security reference monitor Plug and Play manager Object manager Device and file system drivers Cache manager I/O manager Windows USER, GDI Graphics drivers Kernel Hardware abstraction layer (HAL) Hardware interfaces (buses, I/O devices, interrupts, interval timers, DMA, memory cache control, etc.) FIGURE 2-3 Windows architecture CHAPTER 2 System Architecture 47 31 / 34 Modell 3: Client-Server-Modell I Diensterbringung durch eine zentrale Instanz I Client wendet sich mit Dienst-Wunsch an Server I Server erbringt gewünschten Dienst, wenn möglich I Beispiele: Speicherverwaltung im BS, NTP-Server, Drucker-Server, . . . I sog. Mikrokern-Architekturen wenden das Prinzip konsequent auf BS-Komponenten an 32 / 34 Zusammenfassung: Was haben wir gelernt? 1. Es gibt viele BS 2. Was ist UNIX? 3. Lizensierung: Closed Source vs. Open Source 4. Klassifikationskriterien von BS 5. Modellierung/Strukturierung von BS: I I I monolithisch geschichtet Client-Server-Beziehungen 33 / 34 Literaturvorschläge I Andrew S. Tanenbaum: Modern Operating Systems. Pearson Education I Richard Stallings: Operating Systems. Fifth Edition, Prentice-Hall I Dokumentation der Geschichte des Windows-Betriebssystems: http://www.winhistory.de/ I Ellen Siever, Stephen Figgins, Robert Love, Arnold Robbins: Linux in a Nutshell. Sixth Edition, O’Reilly, 2009 I Cameron Newham: Learning the Bash Shell. Third Edition, O’Reilly, 2005 34 / 34 Vorlesung Betriebssysteme I Thema 2: Linux in a Nutshell Robert Baumgartl 05. 11. 2013 1 / 24 Linux I bekanntestes Open-Source-Projekt weltweit I Multiuser-Multitasking-Betriebssystem I Unix-artig I Schöpfer: Linus Torvalds I primär kommandoorientiert, aber auch mit vielen (schönen) bunten Oberflächen bedienbar I außerordentlich gut skalierbar I für sehr viele Plattformen verfügbar (Auswahl): IA-32, IA-64, Sun SPARC, Motorola 68000, PowerPC, ARM, IBM S/390, MIPS, HP PA-RISC, Atmel AVR32, AD Blackfin 2 / 24 Im Anfang war ein Posting . . . From: [email protected] (Linus Benedict Torvalds) Newsgroups: comp.os.minix Subject: What would you like to see most in minix? Summary: small poll for my new operating system Message-ID: <[email protected]> Date: 25 Aug 91 20:57:08 GMT Organization: University of Helsinki Hello everybody out there using minix I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I’d like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons) among other things). I’ve currently ported bash(1.08) and gcc(1.40), and things seem to work. This implies that I’ll get something practical within a few months, and I’d like to know what features most people would want. Any suggestions are welcome, but I won’t promise I’ll implement them :-) Linus ([email protected]) PS. Yes - it’s free of any minix code, and it has a multi-threaded fs. It is NOT protable (uses 386 task switching etc), and it probably never will support anything other than AT-harddisks, as that’s all I have :-(. 3 / 24 Evolution I 17. September 1991: Version 0.01: 241 KiB, 8413 LoC1 I 13. März 1994: Version 1.0.0: 563 KiB, 170.581 LoC I 9. Juni 1996: Version 2.0.0: 2.015 KiB, 716.119 LoC I 9. Oktober 2008: Version 2.6.26.6, mehr als 8 Millionen LoC I 2012: Version 3.6, knapp 15 Millionen LoC I neueste Version stets hier: http://kernel.org/ 1 Lines of Code (Programmzeilen) 4 / 24 Kernel vs. System Mit Linux i. e. S. ist der Kernel, d. h. , das eigentliche Betriebssystem gemeint. Zu einem Linux-System gehört jedoch viel mehr: I Basiswerkzeuge zur Bedienung I Kommandointerpreter (Shell): bash, ksh, csh, tcsh I Entwicklungswerkzeuge: gcc (GNU Compiler Collection) I (textbasierte) Applikationen I grafische Basisschnittstelle: X Window System I Fenstermanager I grafische Applikationen → Gesamtsystem wird manchmal (korrekter) GNU/Linux genannt. 5 / 24 Distributionen I sind Zusammenstellungen des Kernels, von Applikationen und Werkzeugen zur Konfiguration, die ein lauffähiges Gesamtsystem erzeugen I vereinfachen den Konfigurations- und Updateaufwand beträchtlich (Paketmanagement) unterscheiden sich in vielen Einzelaspekten: I I I I I I hauptsächliches Einsatzziel Desktoprechner, Server, eingebettetes System Einstellung zu proprietären Komponenten Sprachanpassung (Lokalisierung) ... Frage nach der besten Distribution führt gemeinhin zu Meinungsverschiedenheiten 6 / 24 Beispiele für populäre Distributionen Name Merkmal Gentoo das System wird grundlegend aus den Quellen erzeugt Fedora freies Linux der Fa. Red Hat SUSE Distribution der Fa. Novell (frei und kommerziell) Debian frei, stabil, (meist) etwas veraltete Applikationen Ubuntu anfängerfreundlich, frei Knoppix bekannte Live-Distribution DVL für die Ausbildung in BS-Sicherheit Openmoko spezialisiert für Smartphones Siehe auch: http://de.wikipedia.org/wiki/Liste_von_Linux-Distributionen http://upload.wikimedia.org/wikipedia/commons/8/8c/Gldt.svg 7 / 24 Womit mache ich . . . Textverarbeitung? openoffice, LATEX Kinoabend? mplayer, totem Instant Messaging? gajim Diashows? gqview, display Bildbearbeitung? gimp, Imagemagick WWW-Recherche? firefox, iceweasel, epiphany Notensatz? lilypond Funktionsplotting? gnuplot Vektorgrafik? xfig Programmeingabe? vi, emacs, joe 8 / 24 Qual der (Editor-)Wahl vi I auf jedem UNIX-System vorhanden I effizient, leichtgewichtig I arbeitet im Terminal emacs I kann alles: editieren, Mail und News lesen, browsen, Terminal bedienen, Kuchen backen . . . I sehr flexibel I schwierig zu konfigurieren (Lisp) I grundlegende Edit-Kommandos sind die gleichen wie in der Bash joe ist ein Behelf, der nicht an die Mächtigkeit der anderen beiden Editoren heranreicht 9 / 24 Neal Stephenson über Emacs “I use Emacs, which might be thought of as a thermonuclear word processor. It was created by Richard Stallman; enough said. It is written in Lisp, which is the only computer language that is beautiful. It is colossal, and yet it only edits straight ASCII text files, which is to say, no fonts, no boldface, no underlining. If you are a professional writer i.e., if someone else is getting paid to worry about how your words are formatted and printed, Emacs outshines all other editing software in approximately the same way that the noonday sun does the stars. It is not just bigger and brighter; it simply makes everything else vanish.” (Neal Stephenson, In the Beginning . . . was the Command Line) 10 / 24 Grafische Nutzeroberflächen I K Desktop Environment (KDE) I GNOME I WindowMaker I Xfce I Ion I awesome Unterscheidungskriterien: I ’Look & Feel’ I Tastaturbedienbarkeit I Umfang (Startzeit, Ressourcenbedarf) Frage nach dem besten Windowmanager → Chaos. 11 / 24 Womit schaue ich Dokumente an? Extension .chm .djvu .doc .dvi .jpg .pdf .ps .svg Betrachter xchm djview openoffice, abiword xdvi gqview acroread, xpdf, evince gv Browser 12 / 24 Erste Hilfe I man <kommando> zeigt die zugehörige Manualseite I info <kommando> dito, jedoch mit emacs-Steuerung I apropos <begriff> zeigt zum Suchbegriff gehörige Kommandos I der Schalter --help gibt zu vielen Kommandos nähere Erklärungen I Das WWW bietet eine Fülle von Hilfen für alle Probleme rund um Linux 13 / 24 Das Manual I Manual-Seiten sind in verschiedene Kategorien eingeteilt (man man) I I I Shellbefehle, z. B. open Systemrufe, z. B. open() Bibliotheksfunktionen, z. B. fopen() I mehrere Sektionen pro Seite: NAME, SYNTAX, BESCHREIBUNG, OPTIONEN, DATEIEN, SIEHE AUCH, FEHLER, und AUTOR I Humorige Bemerkungen sind häufig, vgl. man 3 gets (unter BUGS) oder man rtfm (, sofern installiert) 14 / 24 Die 20 wichtigsten Kommandos – Teil 1 Kdo. ls cd cp mv rm mkdir rmdir chmod less cat w Zweck Verzeichnisanzeige (list) Verzeichniswechsel (change dir) Kopieren von Dateien (copy) Bewegen von Dateien/Verzeichnissen (move) Löschen von Dateien/Verzeichnissen (remove) Verzeichnis anlegen (make dir) Verzeichnis löschen (remove dir) Rechte einer Datei ändern (change mode) seitenweise Anzeige von Dateien Anzeige des Dateiinhalts (catalogue) zeigt an, wer eingeloggt ist (und was er tut) 15 / 24 Die 20 wichtigsten Kommandos – Teil 2 Kdo. grep find man ps kill bg top mount du ln Zweck Suche von Zeichenketten Suche nach Dateien Anzeige von Manualseiten Anzeige von Prozessstatistiken (process state) Zustellung von Signalen Programm in den „Hintergrund“ schicken (background) Anzeige der rechenintensivsten Prozesse Datenträger einbinden (montieren) Anzeige des Platzbedarfs von Dateien (disk usage) Anlegen eines Verweises (Links) aber: nicht jedes zweibuchstabige Kürzel ist ein Kommando! 16 / 24 Konzept: „Alles ist eine Datei“ 3 Kategorien von Dateien: 1. „gewöhnliche“ Datei = unstrukturierte Strom von Bytes 2. Verzeichnis (Directory) = Datei, die Verzeichniseinträge enthält 3. Spezialdateien: I I I I Links (Hard Links, symbolische Links) Geräte (zeichen- oder blockorientiert) „named pipes“ (FIFOs) Sockets Vorteil: einheitliche Behandlung der abstrahierten Objekte. 17 / 24 Die Shell I normaler Nutzerprozess, der kontinuierlich 1. Kommandos einliest, 2. diese ausführt, 3. etwaige Ausgaben des Programms am Bildschirm darstellt. I verschiedene: csh, tcsh, ksh, bash I Folgen von Shell-Kommandos nennt man Shellscript I da die Shell auch Konstrukte für Verzweigungen, Schleifen und Funktionsaufrufe mitbringt, handelt es sich um eine Programmiersprache. I mächtiges Werkzeug 18 / 24 Einfaches Shellscript #!/bin/bash # some sanity checks if test ! -x ‘which mac‘ ; then printf "Please install mac first. Aborting.\n" >&2 exit 127 fi if test ! -x ‘which lame‘ ; then printf "Please install lame first. Aborting.\n" >&2 exit 127 fi # do the work for FILE in *.ape ; do mac "$FILE" "${FILE/ape/wav}" -d lame -h -b320 "${FILE/ape/wav}" "${FILE/ape/mp3}" rm -f "${FILE/ape/wav}" done exit 0 19 / 24 Shell vs. Grafikoberfläche - kein Widerspruch 20 / 24 Kurzer Rundgang durchs Dateisystem . . . machen wir interaktiv. 21 / 24 Was haben wir gelernt? 1. UNIX (in der Gestalt von Linux) ist sehr mächtig und sehr flexibel; es erfordert jedoch eine Portion Einarbeitungsaufwand. 2. Die Shell wird interaktiv bedient. 3. Shellscripts sind Kommandofolgen der Shell; die Syntax ist ein wenig kryptisch, man kann sie aber meistern. 4. Das Dateisystem ist ein hierarchischer Baum. 22 / 24 Literaturvorschläge I Linus Torvalds und David Diamond: Just for Fun. Wie ein Freak die Computerwelt revolutionierte, dtv, 2002 I http://www.bin-bash.de/ 24 / 24 Vorlesung Betriebssysteme I Thema 3: Dateisystem Robert Baumgartl 9. Februar 2015 1 / 35 Wozu ein Dateisystem? Aufgaben von Dateisystemen: I Verwirklichung sinnvoller Abstraktionen zum Strukturieren der abzulegenden Information (Datei, Verzeichnis) I Management des Freispeichers Herausforderungen: I Langsamkeit der Medien, da meist mechanische Operationen notwendig I Umfang der Informationen I Fehlertoleranz Heterogenität: I magnetische Massenspeichermedien I optische I elektrische 2 / 35 Aufbau einer Festplatte I Stapel von rotierenden Magnetplatten, konstante Rotationsgeschwindigkeit (CAV – Constant Angular Velocity) I Rotationsgeschwindigkeit ca. 5400 – 15000 min−1 I 2-16 Platten I konzentrische Spuren (Tracks), ca. 10.000 pro Oberfläche I übereinanderliegende Spuren bilden einen sog. Zylinder I kleinste ansprechbare Einheit: physischer Block („Sektor“; 512 Byte), z.B. 150-300 Sektoren pro Spur I 1 Schreib-Lesekopf pro Plattenoberfläche, radiale Bewegung aller Köpfe gemeinsam 3 / 35 Aufbau einer Festplatte I historisch: Adressierung eines Sektors über {Zylinder, Kopf, Sektor}-Tripel (Cylinder, Head, Sector – CHS) I heute: Logical Block Addressing (LBA), einfache Durchnumerierung aller Blöcke I physisches Layout vor Nutzer verborgen: Abbildung Logischer Blocknummern auf Physische Blocknummern (LBN → PBN) durch Festplattenelektronik 4 / 35 Schematischer Aufbau einer Festplatte Spur Spur Zylinder Platte Abbildung: Seitenansicht Sektor Abbildung: Draufsicht 5 / 35 Optische Medien: Compact Disc (CD) Grundlage: Red Book Standard von Philips und Sony Standard Red Book Yellow Book Green Book Blue Book Orange Book White Book - Kürzel CD-DA CD-ROM CD-I CD-Extra CD-R[W] Video-CD Photo CD Bemerkungen Audio-CD CD Interactive Audio+Daten-CD Recordable CDs Tabelle: Übersicht relevanter CD-Standards 6 / 35 Fakten zur CD I Abtastung mittels eines Infrarotlasers, unterschiedliches Reflexionsverhalten von Pits und Lands I eine (!) Spur (Breite: 0.5 µm), von innen nach außen gelesen, Abstand 1.6 µm I konstante Speicherdichte → Constant Linear Velocity (CLV) → variable Umdrehungsgeschwindigkeit je nach Position auf Medium 2 (CD-Audio) bzw. 3 unabhängige Fehlerkorrektur-Schichten: I I I I I Symbol: 8 Bit Payload pro 14 Bit-Symbol (Eight-to-Fourteen Modulation, EFM) P Frame: SYNC + CTL + 32 Symbole ( 588 Bit, davon 24 Byte Nutzlast) Sektor: 98 Frames á 24 Byte Nutzlast = 2352 Byte Länge kleinste adressierbare Einheit: Sektor (CD-ROM) 7 / 35 Welche Dateisysteme gibt es? BS MS-DOS Windows 9x Windows NT. . . Vista MacOS Linux OS/2 Dateisystem FAT12, FAT16 VFAT NTFS HFS ext2fs, ext3fs HPFS Tabelle: Betriebssystemspezifische Dateisysteme Gute BS lesen auch die Dateisysteme der „Konkurrenz“, sofern diese offen liegen. Zusätzlich gibt es BS-übergreifende Dateisysteme, z. B. IS09660 (Dateisystem der CD-ROM) oder CIFS. 8 / 35 Grundlegende Abstraktionen: Datei Datei = „Ansammlung“ von Nutzdaten + Attribute Beispiele typischer Attribute: I Schutz: Wer darf welche Operation mit Datei ausführen? I Eigentümer der Datei I Beschränkungen der erlaubten Operationen (Read-Only) I Beschränkungen der Sichtbarkeit der Datei (Hidden Flag, .dateiname) I Dateiname I Zeitstempel (letzter Zugriff, letzte Änderung, Kreation) I Größe der Datei I Stellung des Dateipositionszeigers → stat-Kommando unter Linux 9 / 35 Typen von Dateien Unterscheidung von Dateitypen I durch Attribute (Dateinamen, ASCII/binary-Flag), I durch Dateinamen, I durch Magic Word. Ein Magic Word ist eine charakteristische Bytesequenz am Beginn der Datei, anhand derer ihr Typ identifiziert werden kann. Sequenz JFIF GIF89a #!/bin/bash ELF Bedeutung JPEG File Interchange Format Graphics Interchange Format (V.89a) Shell-Skript Executable and Linkable Format Tabelle: Beispiele für Magic Words 10 / 35 Beispiele: JFIF, PDF robge@ilpro121:~/txt/job/htw/bs1$ hexdump -C pic/tux2.jpg 00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 |ÿØÿà..JFIF.....H| 00000010 00 48 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.H..ÿÛ.C........| 00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| * 00000050 01 01 01 01 01 01 01 01 01 ff db 00 43 01 01 01 |.........ÿÛ.C...| 00000060 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| ... robge@ilpro121:~/txt/job/htw/bs1$ hexdump -C select-pages.pdf 00000000 25 50 44 46 2d 31 2e 34 0a 38 20 30 20 6f 62 6a |%PDF-1.4.8 0 obj| 00000010 20 3c 3c 0a 2f 4c 65 6e 67 74 68 20 31 32 35 20 | <<./Length 125 | 00000020 20 20 20 20 20 20 0a 2f 46 69 6c 74 65 72 20 2f | ./Filter /| 00000030 46 6c 61 74 65 44 65 63 6f 64 65 0a 3e 3e 0a 73 |FlateDecode.>>.s| 00000040 74 72 65 61 6d 0a 78 da 8d 8e 31 0a c3 30 0c 45 |tream.xÚ..1.Ã0.E| 00000050 77 9f e2 5f c0 8a 24 47 ae bc 17 4a c6 9c a1 43 |w.â_À.$G...JÆ.¡C| ... 11 / 35 Dateinamenskonventionen Jedes Dateisystem hat Regeln zum Aufbau eines Dateinamens: FAT (File Allocation Table) – MS-DOS I „berüchtigte“ 8.3-Konvention I .COM, .EXE – ausführbare Dateien I .BAT – Batchdateien (analog zu Shellskripten) VFAT – ab Windows 95 I bis 255 Zeichen lang I Unicode-kodiert I keine Unterscheidung von Groß- und Kleinschreibung Unix I unterscheidet Groß- und Kleinschreibung I name.ext eigentlich unüblich, aber trotzdem genutzt 12 / 35 Wurzelverzeichnis, Pfadtrenner Wurzelverzeichnis VFAT: C:\, D:\, . . . , Z:\ Unix: / VMS: [000000] Betriebssystem Windows Unix Multics VMS Trennsymbol \ / > : Tabelle: Trennsymbole für Pfadangaben 13 / 35 (Abstrakte) Operationen über Dateien Operation Open Read Write Seek Close Append Truncate Rename Bemerkungen Vor eigentlichem Zugriff erforderlich (sequentiell) (sequentiell) Verstellen des Dateipositionszeigers nicht vergessen Anfügen von Daten an Dateiende Datei verkürzen (z. B. auf 0) Datei umbenennen 14 / 35 Anmerkungen I Dateien müssen vor Zugriff geöffnet werden. I Lese- und Schreiboperationen nutzen gemeinsam den Dateipositionszeiger I Dieser steht initial auf Position 0 und kann mittels Seek-Operation beliebig versetzt werden. I Lesen und Schreiben versetzt den Dateipositionszeiger ebenfalls. I Wird beim Zugriff das Ende der Datei erreicht, wird i. A. EOF (End of File) gemeldet I Um mit dem Inhalt einer Datei zu arbeiten, muss diese in den Hauptspeicher transferiert oder eingeblendet werden. 15 / 35 Dateifunktionen der C-Bibliothek Funktion fopen() fclose() fread() fwrite() fprintf() feof() ferror() fseek() ftell() flock() Semantik Eröffnen Schließen Lesen Schreiben (formatiertes) Schreiben Test auf Dateiende Test auf Fehler Versetzen des Positionszeigers Abfrage desselbigen Sperren einer Datei mehr: man 3 stdio 16 / 35 C-Bibliotheksfunktionen I gepuffert I definiert in stdio.h I geöffnete Datei wird durch FILE* identifiziert I stdin, stdout, stderr I betriebssystemeunabhängig (portabel) I standardisiert nach ANSI C3.159-1989 17 / 35 Systemrufe zur Dateiarbeit (Unix) Operation open() read() write() lseek() close() link() rename() mmap() Semantik Eröffnen der Datei Leseoperation Schreiboperation Verstellen des Dateipositionszeigers Schließen der Datei Verweis (Hard Link) auf Datei anlegen Datei umbenennen Datei in Hauptspeicher einblenden 18 / 35 Unix-Systemrufe zur Dateiarbeit I definiert in <unistd.h> I standardisiert in POSIX I portabel nur in Unix-Betriebssystemen I geöffnete Datei wird durch Dateideskriptor (integer) identifiziert 19 / 35 Funktionen zur Dateiarbeit (Win32) – kleine Auswahl Operation CreateFile() ReadFile() WriteFile() SetFilePointer() CloseFile() CreateHardLink() MoveFile() CreateFileMapping() Semantik Öffnen (kein Witz!) Lesen Schreiben Dateipositionszeiger setzen Schließen der Datei (Hard Link) anlegen Datei umbenennen (u. a.) Datei in Hauptspeicher einblenden 20 / 35 Systemrufe zur Dateiarbeit (Windows) I MSDN listet 114 Funktionen zur Arbeit mit Dateien I Identifikation geöffneter Objekte mit Handles Beispiel: HANDLE WINAPI CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); 21 / 35 Einige typische Datei-Kommandos in Unix Kommando cp mv rm ln chmod chown dd shred stat Semantik Kopieren (copy) Bewegen (move) Löschen (remove) Verweis anlegen (link) Ändern der Zugriffsrechte (change mode) Ändern des Eigentümers (change owner) Umleitung von Strömen sicheres Löschen Anzeige der Dateiattribute 22 / 35 Kommandos über Massenspeicher und Dateisystem Kommando du df fdisk mount mkfs fsck hdparm Zweck Schätzen des Speicherbedarfs eines Verzeichnisses Anzeige Belegungszustand Partitionierung Montieren des Datenträgers Anlegen eines Dateisystems Prüfen (und Reparieren) der Integrität des Dateisystems Detailinformationen zum Massenspeicher 23 / 35 Verzeichnisse („Ordner“) I Organisation der Dateien auf Massenspeicher I üblich: Hierarchie von Verzeichnissen I bevorzugte Datenstruktur: Baum, gerichteter Graph Wurzelverzeichnis A a B a b Nutzerverzeichnisse C c c c Dateien Abbildung: Zweistufiges Dateisystem 24 / 35 Hierarchien von Verzeichnissen Wurzelverzeichnis A a B B b Nutzerverzeichnisse C c B C b Unterverzeichnisse der Nutzer C c C c c c Nutzerdateien Abbildung: Typisches hierarchisches Dateisystem 25 / 35 Unix-Systemrufe über Verzeichnissen mkdir() Anlegen eines neuen Verzeichnisses rmdir() Löschen eines Verzeichnisses opendir() Eröffnen closedir() Schließen readdir() Sequentielles Lesen der Einträge eines V. scandir() Gezieltes Suchen von Einträgen innerhalb eines V. rewinddir() Zurückstellen des Eintragszeigers symlink() Anlegen eines Soft Link 26 / 35 Verweise (Links) I zusätzliche Verweise auf Verzeichniseinträge I Sinn: Vermeidung von Dateikopien, Vereinfachung der Aktualisierung, Erhöhung der Flexibilität I UNIX: 2 Typen – Soft Links, Hard Links I Systemrufe link(), symlink() I Kommando ln zum Anlegen 27 / 35 Verweise auf Dateien und Verzeichnisse A l B B l2 C c B C C b c C c c c Abbildung: Beispiele für Verweis auf Datei (rot) und Verzeichnis (blau) 28 / 35 Zugriffsrechte von Dateien Abstraktion zur Beschränkung des Zugriffs Wozu? I Schaden durch I I I unkundige Nutzer, bösartige Nutzer und fehlerhafte Software zu minimieren Allgemeines Modell: Zugriffsmatrix I Spalten: (passive) Objekte, z. B. Dateien, die Zugriffsbeschränkungen unterliegen I Zeilen: (aktive) Subjekte, z. B. Nutzer oder Prozesse, deren Zugriff beschränkt werden soll I Inhalt der Elemente: erlaubte Operationen, gewährte Rechte 29 / 35 Beispiel zur Zugriffsmatrix Nutzer A Nutzer B Nutzer C Datei 1 Own/R/W R R/W Datei 2 Own/R/W R I Zugriffsmatrix i. a. spärlich besetzt I → zwei Wege der Dekomposition Datei 3 Own/R/W W Datei 4 R Own/R/W 30 / 35 Dekomposition der Zugriffsmatrix Access Control List (ACL) I Dekomposition der Zugriffsmatrix nach Objekten I für jedes Objekt wird gespeichert, welches Subjekt welche Operation mit ihm ausführen darf im Beispiel: I I I I I Datei 1: A(OWN/R/W), B(R), C(R/W) Datei 2: B(OWN/R/W), C(R) Datei 3: A(OWN/R/W), B(W) Datei 4: B(R), C(OWN/R/W) Capability List I Dekomposition der Zugriffsmatrix nach Subjekten I für jedes Subjekt wird gespeichert, auf welche Objekte es wie zugreifen darf 31 / 35 Beispiele I Read-Only Flag im MS-DOS I rwxrwxrwx-Abstraktion im klassischen UNIX I rwlidka-Rechte im Andrew File System (AFS); (für Verzeichnisse): read, write, lookup, insert, delete, lock, administer 32 / 35 Zugriffsrechte in Unix I jede Datei hat 3 Rechte: Lesen, Schreiben, Ausführen I Rechte werden für 3 Kategorien von Nutzern vergeben: den Eigentümer, die Gruppe, alle anderen Nutzer des Systems I ⇒ 3x3 Bits, die gesetzt oder gelöscht sein können I I Ausführungsrecht für Verzeichnis: man darf hineinwechseln Änderung mittels chmod-Kommando Beispiel: ~> chmod u+rwx g+r-wx o-rwx foo.sh ~> ls -l foo.sh -rwxr----- 1 robge robge 4 2008-10-28 10:26 foo.sh 33 / 35 Rechte der restlichen Nutzer Rechte der Gruppenmitglieder Rechte des Eigentümers Ausgabe des Kommandos ls -l Eigentümer Größe Zeitpunkt der letzten Modifikation Name −rw−r−−−−− 1 robge if 353400 2008−10−28 10:03 foo.txt Typ der Datei Gruppe Anzahl Verzeichnisse Abbildung: Ausgebenene Informationen bei ls -l 34 / 35 Zusammenfassung: Was haben wir gelernt? I Was sind Datei und Verzeichnis? I Dateityp, Namenskonventionen, Pfadsymbole I Was versteht man unter Links? I typische Kommandos, C-Funktionen und Systemrufe zur Dateiarbeit I Wie werden Zugriffsrestriktionen für Dateien realisiert? 35 / 35 Vorlesung Betriebssysteme I Thema 4: Grundlegende Begriffe, Teil 2 Robert Baumgartl 9. Februar 2015 1 / 19 Begriffe: Schnittstelle I beschreibt den statischen Aspekt einer Kommunikationsbeziehung I Kommunikation über Schnittstelle kann synchron und asynchron erfolgen I kann in Hardware oder in Software vorliegen Hardwareschnittstellen – Beispiele I Peripheral Component Interconnect (PCI) I Controller Area Network (CAN) I InfiniBand Softwareschnittstellen = Gesamtheit aller nutzbaren Funktionen einer Bibliothek, eines Betriebssystems, einer Middleware (aka API – Application Programmer’s Interface) Beispiele: POSIX, Win32, Qt-API 2 / 19 Begriffe: Protokoll I I beschreibt den dynamischen Aspekt einer Kommunikation (also den Ablauf) Beispiele I I I Timingdiagramme für das Signalspiel Semantikbeschreibung von Systemrufen Präzedenzen für den Aufruf von Funktionen Protokoll und Schnittstelle bedingen einander! Es gibt proprietäre und offene Schnittstellen und Protokolle. 3 / 19 Beispiel für (Teil einer) Protokollbeschreibung Start open() read() write() close() Abbildung: Typische Präzedenzen bei Funktionen eines Dateisystems 4 / 19 Protokollbeispiel Kommunikation eines Kunden mit dem Clerk bei McDonald’s Clerk Customer "Hi." "Hi." {"Hi", "Hello"} "Whaddaya wanna?" "A Burger." {"Burger", "Fries", "Chicken"} "Anything else?" {"Yes", "No"} "No" "Drink?" "Large Coke." {"small", "medium", "large"} x {"Coke", "Fanta", "Sprite"} "Takeaway?" "No." {"Yes", "No"} computation time "$4.99" pay "Bye." {"Bye", "Get lost!"} "Bye." t 5 / 19 Aktivitäten und Ressourcen In einem Rechensystem gibt es zwei Kategorien von grundsätzlichen Objekten 1. Aktivitäten: das, was abgearbeitet wird I I I I I I Task Prozess Thread Routine ... (siehe später) 2. Ressourcen: das, was Aktivitäten „zum Leben“ benötigen 6 / 19 Ressourcen I „alles das, was keine Aktivität ist“ I Aktivitäten konkurrieren um Ressourcen I existieren in allen Schichten eines Systems I Beispiele: Datei, Festplatte, Programmcode, Hauptspeicherblock I = Hardware und alle passiven Abstraktionen eines Rechensystems (d. h. auch CPU und Geräte) I besitzen zu jedem Zeitpunkt einen inneren Zustand (z. B. CPU: Gesamtheit der Inhalte aller Register) I Ressourcen werden durch Aktivitäten angefordert,durch eine zentrale Instanz zugeteilt und nach Nutzung durch die Aktivität zurückgegeben(← Protokoll!) 7 / 19 Entziehbare Ressourcen Def. Eine entziehbare Ressource kann nach ihrer Zuteilung der Aktivität jederzeit entzogen werden. Der Vorgang ist für die Aktivität transparent. Ablauf: 1. Aktivität anhalten 2. Zustand der Ressource sichern (z.B. auf Datenträger schreiben) 3. [Ressource anderweitig verwenden] 4. Zustand der Ressource restaurieren 5. Aktivität fortsetzen Voraussetzung für Entziehbarkeit: I Zustand der Ressource ist vollständig auslesbar I Zustand der Ressource kann beliebig manipuliert werden. 8 / 19 Entziehbare Ressourcen - Beispiele I CPU (Zustand kann in den Hauptspeicher ausgelagert werden) I Hauptspeicherblock (Zustand kann auf Massenspeicher ausgelagert werden) I Datei Die meisten Ressourcen sind nicht entziehbar: I CPU-Cache I Drucker I Netzwerkkarte 9 / 19 Exklusiv nutzbare Ressourcen Def. Eine exklusiv nutzbare Ressource darf zu jedem Zeitpunkt maximal von einer Aktivität genutzt werden. I Beispiele: Hardware, (beschreibbarer) Speicher, zum Schreiben eröffnete Datei I BS muss Exklusivität durchsetzen (→ Synchronisationsmechanismen) Zuteilung kann mittels verschiedener Strategien erfolgen: I I I I Fairness Minimierung der Wartezeit Garantie einer maximalen Wartezeit 10 / 19 Klassifikation und Beispiele für Ressourcen entziehbar Prozessor, Speicher gleichzeitig nutzbar Programmcode, Datei, Speicher wiederverwendbar Prozessor, Datei, Speicher physisch Prozessor, Speicher, Geräte nicht entziehbar Datei, alle verbrauchbaren BM exklusiv nutzbar Prozessor, Drucker, Signal verbrauchbar Signal, Nachricht, Interrupt logisch oder virtuell Datei, Signal, Prozessor (!) Tabelle: Klassifikation von Ressourcen 11 / 19 Ressourcentransformation Applikationsebene Ebene des Filesystems Ebene der Treiber Byte einer Datei log. Block, z.B. 4 kB phys. Sektor, 512 Byte Hardware−Ebene Abbildung: Transformation der Ressource physischer Sektor in Datei Es kann dabei sogar eine neue Qualität entstehen: Speicher + Identifikator + Programmcode = neuer Prozess 12 / 19 User Mode und Kernel Mode I Idee: nur in einem privilegierten Modus (Kernel Mode) dürfen alle Operationen ausgeführt werden (z.B. Zugriff auf die Hardware, Manipulation von systemrelevanten Datenstrukturen wie der Prozesstabelle) I dieser ist dem Betriebssystem vorbehalten I Applikationen werden in einem restriktiven Modus (User Mode) ausgeführt (z.B. erfolgt automatische Prüfung der Gültigkeit jeder Speicherreferenz) I bei Verletzung der Restriktionen wird die Applikation abgebrochen I Unterscheidung Kernel Mode vs. User Mode analog zur Einteilung Administratoren vs. gewöhnliche Nutzer I Ziel: Etablierung eines grundlegenden Schutzkonzeptes 13 / 19 User Mode und Kernel Mode Was darf man nur im Kernel Mode? I neuen Prozess erzeugen I Treiber ins System laden oder daraus entfernen I generell: Diensterbringung des Betriebssystems I nicht jedoch: typische Adminaufgaben Die CPU muss User Mode/Kernel Mode unterstützen, d.h., verschiedene Privilegierungsmodi unterscheiden. 14 / 19 Systemruf Damit der „gewöhnliche“ Nutzer die Funktionen des Kernels überhaupt anwenden darf, gibt es den Mechanismus des Systemrufs. I BS bietet dem Programmierer Funktionen, diese werden über Systemrufe zur Verfügung gestellt I Gesamtheit aller Systemrufe eines BS ist dessen Application Programmer’s Interface (API) I Nutzung analog den Funktionen einer Bibliothek mit einem Unterschied: Diensterbringung erfolgt im Kernel Mode I → gewöhnlicher Funktionsaufruf als Mechanismus unbrauchbar! I Systemrufe können blockieren! 15 / 19 Prinzip eines Systemrufs User Mode Kernel Mode System− eintritt Applikation Betriebssystem System ruf System− dienst System− austritt 16 / 19 Ablauf eines Systemrufs count = read(fd, buffer, nbytes); user space return to caller library call TRAP into kernel 5 put # for read in register 10 4 11 9 adjust stack 6 call read kernel space dispatch syscall 3 push fd 2 push &buffer 1 push nbytes 7 user program 8 syscall handler Abbildung: Allgemeiner Ablauf eines Systemrufs read() 17 / 19 Ablauf von WriteFile() in Windows 2000/XP/Vista Win32 application Call WriteFile(...) KERNEL32.DLL Call NtWriteFile() Return to Caller NtWriteFile() in NTDLL.DLL int 0x2e Return to Caller WriteFile() in Win32− specific Used by all subsystems User Mode Kernel Mode Software Interrupt SystemService in NTOSKRNL.EXE NtWriteFile() in NTOSKRNL.EXE Call NtWriteFile() Dismiss Interrupt Do the Operation Return to Caller Quelle: David Solomon, Inside Windows XP, Microsoft Press, 2000 18 / 19 Was haben wir gelernt? 1. Protokoll und Schnittstelle 2. Ressourcen I I I entziehbare exklusiv nutzbare Ressourcentransformation 3. Kernel Mode und User Mode 4. Was ist ein Systemruf? 19 / 19 Vorlesung Betriebssysteme I Thema 5: Aktivitäten Robert Baumgartl 9. Februar 2015 1 / 34 Prozesse Def. Ein Prozess ist ein in Ausführung befindliches Programm. I Lebenszyklus: Erzeugung → Abarbeitung → Beendigung I benötigt Ressourcen bei Erzeugung (Hauptspeicher, eineindeutigen Identifikator PID, Programmcode) I benötigt weitere Ressourcen im Laufe seines Lebens, nicht mehr benötigte Ressourcen gibt er i. a. zurück I Jeder Prozess besitzt einen virtuellen Prozessor, d. h. CPU wird zwischen allen Prozessen geteilt (jeder erhält CPU für eine gewisse Zeitspanne, vgl. folgende Abbildung) I Hauptmerkmal: Jeder Prozess besitzt einen eigenen Adressraum (jeder Prozess denkt gewissermaßen, er sei allein im System) I Jeder Prozess besitzt einen Vaterprozess sowie u. U. Kindprozesse 2 / 34 ... ... ... P3 ... P2 ... P1 ... Virtuelle vs. reale CPU virtuelle CPU virtuelle CPU virtuelle CPU ... Px ... Transformation reale CPU Abbildung: Virtuelle vs. reale CPU 3 / 34 I Umschaltungeines zwischen Prozessen: Context Switch durch Zustandsmodell Prozesses das Betriebssystem Drei grundlegende Globalzustände werden stets unterschieden: aktiv : Prozess wird abgearbeitet. Er besitzt alle angeforderten Ressourcen und die CPU. bereit : Prozess besitzt alle angeforderten Ressourcen jedoch nicht die CPU. wartend : Prozess wartet auf Zuteilung einer durch ihn angeforderten Ressource und wird nicht abgearbeitet. 1 bereit aktiv 2 3 4 wartend 4 / 34 Zustandsübergänge (Transitionen) bei Prozessen 1. aktiv → bereit: Aktiver Prozess wird verdrängt (Ursache z. B. höherpriorisierter Prozess wurde bereit oder Zeitscheibe abgelaufen) 2. bereit → aktiv: wie 1. 3. aktiv → wartend: Aktiver Prozess geht in Wartezustand (er hat eine Ressource angefordert, deren Zuteilung ihm verweigert wurde; er blockiert) 4. wartend → bereit: wartender Prozess erhält angeforderte Ressource schließlich zugeteilt. 5 / 34 Zustandsübergänge cont’d I bereit → wartend: unmöglich (ein bereiter Prozess kann nichts tun, also auch keine Ressource anfordern, die ihm verweigert wird) I wartend → aktiv: nicht sinnvoll (Prozess erhält eine Ressource, auf die er wartet, rückgebender aktiver Prozess würde für Ressourcenrückgabe „bestraft“) I Es gibt stets einen aktiven Prozess (CPU kann nicht „leerlaufen“), falls keine Nutzarbeit anliegt Idle-Prozess I Jede Ressourcenanforderung wird irgendwann erfüllt. I Prozesszustandsdiagramme in realen Systemen sehen häufig komplexer aus (sind es aber nicht). 6 / 34 Prozesszustände im Linux-Kernel 2.6 existing task calls TASK_ZOMBIE fork() and creates scheduler dispatches task to run: schedule() calls context_switch() a new process (task is terminated) task exits via do_exit() task forks TASK_RUNNING TASK_RUNNING (ready but not running) (running) task is preempted by higher priority task task sleeps on wait queue for a specific event TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE event occurs and task is woken up and placed back on the run queue (waiting) Quelle: Robert Love, Linux Kernel Development, 2005 7 / 34 Prozesszustände im Windows NT/2000/XP Create and initialize thread object Reinitialize Initialized Set object to signaled state Terminated Execution completes Place in ready queue Thread waits on an object handle Waiting Ready Resources become available Resources unavailable Transition Running Select for execution Preempt Standby Preempt (or time quantum ends) Contex−switch to it and start its execution (dispatching) Quelle: David Solomon, Inside Windows 2000, Microsoft Press, 2000 8 / 34 Speicherabbild I jeder Prozess besitzt eigenen Adressraum (Größe systemabhängig, typisch 232 Bytes) I Adressraum ist exklusiv (Ausnahme: Shared-Memory-Segmente) Bestandteile (Abb. 10) eines Adressraums in UNIX: I I I I I Text: Programmcode Data: initialisierte Daten BSS: uninitialisierte Daten, “Heap” Stack 9 / 34 Prinzipieller Adressraumaufbau eines Prozesses High Umgebung, Argumente Stack "break" Heap uninitialisierte Daten (BSS) null−initialisiert initialisierte Daten Text aus Datei eingelesen durch exec() Low 10 / 34 Prozessverwaltung I Prozesse werden unterbrochen und fortgesetzt (Wechsel zwischen bereit und aktiv) I → alle Informationen, die für Fortsetzung benötigt werden (= Mikrozustand), müssen archiviert werden I → Prozesstabelle aka Process Control Block (PCB) I konkrete Ausprägung der Parameter stark systemabhängig I Beispiel eines Eintrags: Tabelle 1 I Linux: struct task_struct in include/linux/sched.h; ca. 1.7 kBytes groß 11 / 34 Mikrozustand eines Prozesses Prozessverwaltung Speicherverwaltung Dateiverwaltung Register Zeiger auf Text-Segment Wurzelverzeichnis Befehlszeiger Zeiger auf Data-Segment Arbeitsverzeichnis Flagregister Zeiger auf Stack offene Dateideskriptoren Globalzustand User ID Priorität Gruppen-ID Prozess-ID ID des Vaters Zeitstempel erhaltene CPU-Zeit Tabelle: Typischer Eintrag in der Prozesstabelle 12 / 34 Informationen zu Prozessen: das Kommando ps gibt tabellarisch zu jedem Prozess des Nutzers aus I PID (Prozess-ID) I TTY (das zugehörige Terminal) I Zustand (Status) des Prozesses I die bislang konsumierte CPU-Zeit I das zugrundeliegende Kommando 13 / 34 Kommando ps (Fortsetzung) Kommandoswitches von ps, die Sie brauchen werden: -A listet alle Prozesse r listet alle bereiten Prozesse (, die sich die CPU teilen) X gibt Inhalt des Stackpointers und einiger weiterer Register aus f zeichnet Verwandtschaftsverhältnisse mit ASCII-Grafik (besser: pstree-Kdo.) -l langes Format (zusätzlich UID, Parent PID, Priorität, Größe) Ein falscher Kommandozeilenparameter gibt eine kurze Zusammenfassung der gültigen Switches aus. Achtung: Die Syntax der Optionen von ps ist kompliziert; manchmal mit vorangestelltem ’-’, manchmal ohne. 14 / 34 Weitere wichtige Prozess-Kommandos I top - kontinuierliche Prozessbeobachtung I pstree - (text-)grafische Veranschaulichung von Prozessverwandschaften I pgrep - Suche nach Prozessen mittels regulärer Ausdrücke Beispiel: pgrep -l "[[:alpha:]]*d\>" listet die PID und Namen aller Daemon-Prozesse I nice - Setzen der Prozesspriorität I kill - Senden von Signalen 15 / 34 Erzeugung von Prozessen I Nur ein Prozess kann einen anderen Prozess erzeugen (lassen), z. B. durch I I I I I Mechanismus: Systemruf I I I Doppelklick auf ein Icon Eingabe eines Kommandos Abarbeitung eines Skriptes Bootvorgang des Rechners UNIX: fork() Win32: CreateProcess() erzeugter Prozess landet zunächst im Bereit-Zustand 16 / 34 Beispiel: Prozesserzeugung im Shellskript #!/bin/bash # number of xterms to start if [ "$1" == "" ] then iterations=1 else iterations=$1 fi # do the (dirty) work for (( count=0; count < $iterations; count++)) do xterm & done # finish(ed) exit 0 17 / 34 Erzeugung eines Unix-Prozesses mittels fork() pid_t fork (void) ; I erzeugt identische Kopie des rufenden Prozesses, mit differierendem PID und PPID (Parent Process Identificator) I beide Prozesse setzen nach fork() fort und sind fortan unabhängig voneinander I Es ist nicht vorhersehbar, ob Vater oder Sohn zuerst fork() verlassen Resultat: I I I Vater: -1 im Fehlerfalle, PID des Sohnes ansonsten Sohn: 0 I Vater-Sohn-Verwandschaft I Vater und Sohn arbeiten identischen Code ab, haben aber private Variablen 18 / 34 Typischer Einsatz von fork() int main(int argc, char* argv[]) { pid_t ret; ret = fork(); if (ret == -1) { printf("fork() failed. Stop.\n"); exit(EXIT_FAILURE); } if (ret == 0) { /* Sohn */ printf("Ich bin der Sohn!\n"); exit(EXIT_SUCCESS); } else { /* Vater */ printf("Ich bin der Vater!\n"); printf("Der PID des Sohnes betraegt %d.\n", ret); exit(EXIT_SUCCESS); } } 19 / 34 Wieviel Prozesse schlafen? #include <unistd.h> int main(void) { fork(); fork(); fork(); sleep(60); return 0; } 20 / 34 Variablen sind privat int var = 42; int main(int argc, char* argv[]) { pid_t ret; if ((ret = fork())== -1) { printf("fork() failed. Stop.\n"); exit(EXIT_FAILURE); } if (ret == 0) { /* Sohn */ var = 32168; printf("Sohns ’var’ hat den Wert %d.\n", var); sleep(5); printf("Sohns ’var’ hat (immer noch) den Wert %d .\n", var); exit(EXIT_SUCCESS); } else { /* Vater */ sleep(2); printf("Vaters ’var’ hat den Wert %d.\n", var); exit(EXIT_SUCCESS); } } 21 / 34 Die Bibliotheksfunktion system() int system (const char∗ string) ; I führt das Kommando string mittels /bin/sh -c aus I string kann Kommando und dessen Parameter enthalten I kehrt erst zurück, wenn Kommando beendet wurde I kombiniert fork() und exec() 22 / 34 Überlagerung des Prozessabbilds mittels execl() I execl() übernimmt (u. a.) eine Pfadangabe einer ausführbaren Binärdatei als Parameter I ersetzt den aktuell abgearbeiteten Programmcode durch diese Binärdatei I springt diesen Code sofort an und beginnt, diesen abzuarbeiten I kehrt nur im Fehlerfalle zurück (z. B. bei falscher Pfadangabe) I Rückkehr in Ausgangsprozess unmöglich (!) I Systemruf-Familie: 5 Rufe mit sehr ähnlicher Semantik (execl(), execle(), execv(), execlp() und execvp()) I erzeugt keinen neuen Prozess 23 / 34 Überlagerung des Prozessabbilds mittels execl() #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { int ret; printf("%s vor Aufruf von execl()\n", argv[0]); ret = execl("/bin/ls", "ls", NULL); if (ret == -1) { printf("execl() ging schief. Und nun?\n"); exit (EXIT_FAILURE); } /* wird nicht erreicht ! */ printf("%s nach Aufruf von execl()\n", argv[0]); exit (EXIT_SUCCESS); } 24 / 34 Beendigung von Prozessen Beendigung kann selbst oder durch anderen Prozess erfolgen (falls dieser die Rechte dazu besitzt) I Selbstbeendigung: I I I I Verlassen von main(), return innerhalb von main(), exit() an beliebiger Stelle im Programm, z. B. als Folge eines Fehlers Fremdbeendigung: I I Zustellung eines Signals durch anderen Prozess fataler Fehler durch den Prozess selbst (Division durch Null, illegale Instruktion, Referenz eines ungültigen Zeigers, . . . ) 25 / 34 Möglichkeit zur Beendigung: durch das System #include <stdio.h> int main(int argc, char* argv[]) { int ret = 42; int x = 0; ret = ret / x; printf("Geschafft!\n"); return 0; } Abarbeitung: robge@ilpro121:~> ./div-by-zero Gleitkomma-Ausnahme 26 / 34 Möglichkeit der Beendigung: exit (mit Rückkehrcode) Listing 1: Generierung eines Rückkehrcodes (retval.c) #include <stdlib.h> int main(int argc, char* argv[]) { if (argc==2) { exit (atoi(argv[1])); } else { exit(42); } } Listing 2: Abfrage des Rückkehrcodes im Shellskript #!/bin/bash ./retval 14 echo $? ./retval echo $? 27 / 34 Synchronisation mittels wait() pid_t wait( int ∗status) ; I bringt den rufenden Prozess in den Wartezustand I dieser wird (automatisch) wieder verlassen, wenn ein (beliebiger) Kindprozess terminiert I falls kein Kindprozess existiert, wird einfach fortgesetzt I status enthält Statusinformationen zum Kindprozess (u. a. Rückkehrcode) Resultat: I I I -1 bei Fehler PID des beendeten Kindprozesses ansonsten → zur Synchronisation zwischen Vater und Sohn nutzbar 28 / 34 Beispiel 1 zu wait() #include #include #include #include #include <sys/types.h> <sys/wait.h> <stdio.h> <stdlib.h> <unistd.h> int main(int argc, char* argv[]) { pid_t ret; ret = fork(); if (ret == -1) { perror("fork"); exit(EXIT_FAILURE); } if (ret == 0) { /* Sohn */ printf("Sohn geht schlafen...\n"); sleep(10); printf("Sohn erwacht und endet.\n"); exit(EXIT_SUCCESS); } else { /* Vater */ printf("Vater wartet auf Sohns Ende.\n"); ret = wait(NULL); if (ret == -1) { perror("wait"); exit(EXIT_FAILURE); } printf("Vater endet (nach Sohn).\n"); exit(EXIT_SUCCESS); } } 29 / 34 Beispiel 2 zu wait() #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, { sleep(20); fork(); sleep(20); fork(); wait(NULL); sleep(20); fork(); sleep(20); return 0; } char* argv[]) /* 1. */ /* 2. */ /* 3. */ Wann sind welche Prozesse im System? 30 / 34 fork(), exec() und wait() zusammen: eine Shell Eine Shell tut im Prinzip nichts weiter als: 1: loop 2: Kommando → von stdin einlesen 3: fork() 4: Sohnprozess überlagert sich selbst mit Kommando && Vater wartet auf die Beendigung des Sohnes 5: end loop Beispiel: minishell.c (extern, da zu groß) 31 / 34 Windows: CreateProcess() I keine Verwandtschaft zwischen Prozessen → keine Hierarchie I legt neuen Adressraum an (→ neuer Prozess) I startet in diesem einen Thread, der das angegebene Programm ausführt I gewissermaßen Hintereinanderausführung von fork() und exec() BOOL CreateProcess ( LPCTSTR lpApplicationName, // pointer to name of executable module LPSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current directory name LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 32 / 34 Ist das alles zu Aktivitäten? Mitnichten! I vfork(), clone(), . . . I Threads I Coroutinen und Fibers I Kommunikation I Synchronisation 33 / 34 Was haben wir gelernt? 1. Begriff des Prozesses 2. Zustände und Transitionen zwischen ihnen 3. Prozesserzeugung in Unix mittels fork() 4. Überlagerung des Prozessabbilds mittels exec() 5. Methoden der Prozessbeendigung 6. einfache Synchronisation mittels wait() 34 / 34 Vorlesung Betriebssysteme I Thema 6: Kommunikation Robert Baumgartl 9. Februar 2015 1 / 38 Einige Gedanken Kommunikation = Übertragung von Informationen zwischen Aktivitäten I meist mit Synchronisation (d. h., zeitlicher Koordination) verbunden I Synonym: Inter Process Communication (IPC) I Vielzahl an Mechanismen, „historisch gewachsen“ I Teilnehmer benötigen gemeinsam genutzte Ressource I Identifikation/Authentisierung der Teilnehmer erforderlich 2 / 38 Beispiele für IPC-Mechanismen (Auswahl) I Datei I Pipe I Signal I benannte Pipe (FIFO) I Socket I gemeinsam genutzer Speicher (Shared Memory) I Nachrichten I Mailboxen I speichereingeblendete Datei (memory-mapped File) I entfernter Prozeduraufruf (Remote Procedure Call) I Clipboard I ... 3 / 38 Kategorisierung von IPC-Mechanismen Interprozeßkommunikation (IPC) Synchronisation Semaphore Signale Kommunikation speicherbasiert strombasiert nachrichtenbasiert Shared Memory Pipe Message Passing Named Pipe Message Queue 4 / 38 Kommunikationsbeziehungen Anzahl der Teilnehmer: I 1:1 I 1:m I n:1 I n:m Gleichzeitigkeit von Hin- und Rückkanal: I unidirektional I bidirektional weitere Aspekte: I lokale vs. entfernte Kommunikation I direkte vs. indirekte Kommunikation 5 / 38 Synchrone und Asynchrone Kommunikation Sendeoperation (Send) I synchron: Sender wartet (blockiert), bis Empfänger die Information entgegengenommen hat (implizite Quittung) I asynchron: Sender setzt nach dem Senden einer Nachricht sofort seine Arbeit fort („No-Wait-Send“, „Fire and Forget“); Beispiel: Telegramm Empfangsoperation (Receive) I synchron: Die Empfangsoperation blockiert den Empfänger so lange, bis Information eintrifft. I asynchron: Empfänger liest Information, falls empfangen wurde und arbeitet anschließend weiter, auch wenn nichts empfangen wurde 6 / 38 Synchrone vs. Asynchrone Operationen synchrone Operationen: I direkte Zustellung der Informationen (ohne Zwischenspeicher) I implizite Empfangsbestätigung I i. a. einfacher zu programmieren I standardmäßig arbeiten Kommunikationsoperationen in Unix synchron asynchron: I Nachricht muss zwischengespeichert werden I Vorteil: wenn ein kommunizierender Prozess abbricht, dann wird der Partner nicht unendlich blockiert I kein Deadlock möglich (gegenseitige Blockierung infolge fehlerhafter Programmierung) I Benachrichtigung des Empfängers u. U. kompliziert 7 / 38 Verbindungsorientierte und verbindungslose Kommunikation Ablauf Beispiele verbindungsorientiert verbindungslos 3 Phasen: Aufbau der Verbindung Datenübertragung Abbau der Verbindung 1 Phase: (analoges) Telefon TCP Pipe Datenübertragung Telegramm IP Signal 8 / 38 Verbindungsarten Unicast Punkt-zu-Punkt-Verbindung, Direktverbindung, 2 Teilnehmer Multicast 1 Sender, mehrere (aber nicht alle) Empfänger, Gruppenruf Broadcast 1 Sender, alle Empfänger (z. B. eines Subnetzes) 9 / 38 Kommunikation über Datei I ältester IPC-Mechanismus I Sender schreibt Daten in Datei I Empfänger liest Daten aus Datei I nachteilig: zweimaliger Zugriff auf Massenspeicher I aber: es gibt auch Dateisysteme im RAM I nachteilig: überlappender Zugriff durch Sender und Empfänger I Lösung: Sperren der Datei (File Locking), z. B. mittels lockf() I Beispiel: filelock.c (extern) I Problem: Sperren setzt Wohlverhalten voraus 10 / 38 Kommunikation mittels Pipe („Röhre“) int pipe(int filedes[2]); I liefert Feld von 2 Dateideskriptoren zurück (einer zum Lesen, einer zum Schreiben) I Zugriff wie auf eine Datei (read(), write(), close()), jedoch kein open(), lseek() I Datenübertragung innerhalb eines Prozesses sinnlos?! I Woher weiß Empfänger, dass die Pipe existiert? 11 / 38 Vorgehensweise 1. Prozess ruft pipe() → Pipe wird durch BS angelegt. 2. Prozess ruft fork() (Deskriptoren werden vererbt!). 3. Jeder Prozess schließt einen seiner Deskriptoren. (Verständigung erfolgt) 4. Datenübertragung mittels read() bzw. write() 5. Beide Prozesse rufen close() → Pipe wird nach zweitem close() durch BS vernichtet 12 / 38 Veranschaulichung der Pipe-Erstellung 1 π π 1 fd[0] fd[1] R W 2 fork() 2 fd[0] fd[1] R W 3 fd[0] fd[1] fd[0] fd[1] R W R W 4 Daten 13 / 38 Eigenschaften der Pipe I stets unidirektional (→ für bidirektionale Übertragung 2 Pipes nötig) I keine Synchronisation beim Schreiben (Daten werden im Kern gepuffert) I Schreiboperationen, die weniger als PIPE_BUF1 Daten umfassen, müssen atomar (in einem Rutsch) erfolgen. I keine persistente Ressource (verschwindet nach letztem close()) I nur zwischen verwandten Prozessen möglich! 1 Linux gegenwärtig: 4096 Bytes; vgl. limits.h 14 / 38 Pipe: problematische Situationen I Lesen von einer eröffneten Pipe, die keine Daten enthält, blockiert. Wird danach die Schreibseite geschlossen, kehrt read() mit Resultat 0 zurück. I Leseoperation aus Pipe mit ungültigem Filedeskriptor – liefert Fehler EBADF (Bad File Descriptor) I Leseoperation aus Pipe, die nach Schreibvorgang geschlossen wurde – liefert zunächst Daten, dann 0 als Resultat = b End of File (EOF) I I Schreiboperation auf Pipe, deren Leseseite geschlossen – liefert Signal SIGPIPE an schreibenden Prozess Prozess(e) enden mit eröffneter Pipe – Filedeskriptoren werden bei Prozessbeendigung automatisch geschlossen Literatur: man 7 pipe 15 / 38 Anwendungsbeispiel Pipe-Operator (‘|’) der Shell zur Verknüpfung von stdout des Senders mit stdin des Empfängers: robge@ipaetz2:~$ du | sort -n -r | less Beispiel 2: simplepipe.c (extern) 16 / 38 Putting it all together: popen() FILE *popen(const char *cmd, const char *type); I I legt eine Pipe an, forkt den rufenden Prozess und ruft im Kind eine Shell auf, die cmd ausführt Resultat: Zeiger auf I/O-Strom, der I I I mit stdin von cmd verbunden ist, wenn type == "w" oder mit stdout von cmd verbunden ist, wenn type == "r". Lese- oder Schreiboperation geschehen also mit Pipe, die mit ge-fork()-tem Prozess cmd verbunden ist I muss mit pclose() geschlossen werden I erleichtert Kommunikation C-Programm ↔ Shellkommando Beispiel: popen.c (extern) 17 / 38 Signale I Mittel zur Signalisierung zwischen Prozessen bzw. BS und Prozessen I Übermittlung einer Information, ohne dass Prozess aktiv beteiligt I Ursprung: UNIX I Generierung → Zustellung → Behandlung (Reaktion auf Signal) I jedes Signal hat Nummer, Name, Defaultaktion I meist (aber nicht immer) keine Datenübertragung I Verwandschaft der Partner ist nicht notwendig 18 / 38 Signale – Prinzipieller Ablauf 1. Sende-Prozess generiert ein Signal 2. System stellt das Signal dem Empfänger-Prozess zu 3. Wenn Empfänger Signalhandler installiert hat → Aufruf des Signalhandlers (asynchron zur Programmausführung) 4. Wenn kein Signalhandler installiert → Ausführung der Default-Aktion (z. B. Abbruch, Ignorieren) 19 / 38 Signale unter Unix (Übersicht) Name SIGHUP SIGINT SIGILL SIGKILL SIGSEGV SIGPIPE SIGCHLD SIGSTOP SIGTSTP SIGCONT Def.-Aktion Abbruch Abbruch Abbruch Abbruch Coredump Abbruch Ignoriert Stop Stop Semantik Verbindung beendet (Hangup) CTRL-C von der Tastatur Illegale Instruktion Sofortige Beendigung Segmentation Violation Schreiben in ungeöffnete Pipe Kind-Prozess beendet Anhalten des Prozesses CTRL-Z von der Tastatur Fortsetzen eines angehaltenen Prozesses Tabelle: Auswahl von Signalen nach POSIX vollständige Übersicht: man 7 signal 20 / 38 Senden von Signalen an der Kommandozeile Senden mit dem (externen) Kommando kill: robge@hadrian:~$ while true ; do echo -n; done & [1] 6578 robge@hadrian:~$ kill -SIGQUIT 6578 [1]+ Verlassen while true; do echo -n; done Generierung bestimmter Signale auch mit der Tastatur möglich: Signal SIGINT SIGQUIT SIGTSTP erzeugende Tastaturkombination Ctrl-C Ctrl-4 oder Ctrl-\ Ctrl-Z 21 / 38 Signale in der Bash Einrichtung eines Signalhandlers mittels trap #!/bin/bash trap "echo CTRL-C gedrà 14 ckt. Na fein." SIGINT trap "echo CTRL-Z gedrà 14 ckt. Mach ruhig weiter so." SIGTSTP trap "echo Auch SIGQUIT kann mir nix anhaben." SIGQUIT echo Entering loop while true ; do echo -n ; done Handler wird I (asynchron) angesprungen, I ausgeführt, und I es wird am Unterbrechungspunkt fortgesetzt. Handler darf nur (externe) Kommandos enthalten, keine Bash-Instruktionen. 22 / 38 Noch ein Bash-Beispiel laufschrift.c (extern) Probieren Sie: robge@hadrian:~$ ps x 5341 pts/5 S+ 5343 pts/0 S+ robge@hadrian:~$ kill robge@hadrian:~$ kill robge@hadrian:~$ kill usw. | grep "./laufschrift" 0:00 ./laufschrift 0:00 grep ./laufschrift -SIGSTOP 5341 -SIGCONT 5341 -SIGSTOP 5341 23 / 38 Signale in C – Teil 1: Senden int kill(pid_t pid, int sig); I sendet das durch sig spezifizierte Signal an Prozess mit PID pid I Zuvor wird geprüft, ob der ausführende Nutzer dazu berechtigt ist. I Spezifikation des Signals: SIGHUP, SIGQUIT, SIGKILL usw., vgl. Headerdatei bits/signum.h I wenn pid == -1, dann wird das betreffende Signal an jeden Prozess geschickt, für den der Nutzer dieses Recht hat (Vorsicht!) 24 / 38 Was passiert nun bei Zustellung eines Signals? Behandlung bei Zustellung: I nichtabfangbares Signal (KILL, STOP) → zugeordnete Aktion {Abbruch, Stop} wird ausgeführt I abfangbares Signal: wenn kein Signalhandler installiert → Default-Aktion {Abbruch, Stop, Ignorieren} ausgeführt I wenn entsprechender Handler installiert → Handler wird (asynchron zur Programmausführung) aufgerufen Anmerkungen: I abfangbares Signal kann auch ignoriert werden 25 / 38 Signale in C – Teil 2: Installation eines Signalhandlers void (*signal(int signum, void (*handler)(int)))(int); fieses Konstrukt; Analyse: I I signal() ist ein Systemruf übernimmt 2 Parameter: I I I signum – Nummer des Signals, für das ein Handler installiert werden soll handler – Zeiger auf eine Funktion, die einen Integer übernimmt und nichts zurückliefert Rückgabewert: Zeiger auf eine Funktion, die einen Integer übernimmt und nichts zurückliefert (genauso wie handler()) 26 / 38 Was bedeutet das? I Handler ist die Funktion, die angesprungen wird, sobald das entsprechende Signal zugestellt wird I Parameter des Handlers ist die (konkrete) Nummer des Signals, da es jederzeit möglich ist, einen Handler für verschiedene Signale zu installieren Resultat: I I I SIG_ERR bei Fehler ansonsten Zeiger auf den vorherigen Handler Anstatt des Handlers kann auch übergeben werden: I I I SIG_IGN → Signal soll ignoriert werden SIG_DFL → Default-Aktion wird eingestellt. 27 / 38 Beispiel 1: Handler für SIGINT (Ctrl-C) #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <signal.h> long inc = 1; void ctrl_c_handler (int c) { inc = ( (inc==1) ? -1 : 1); return; } int main(void) { long count; sig_t ret; ret = signal(SIGINT, (sig_t) &ctrl_c_handler); if (ret == SIG_ERR) { perror("signal"); exit(EXIT_FAILURE); } /* output count continuously */ for (count=0; ; count+=inc) { printf("%08li\n", count); } exit(EXIT_SUCCESS); } (signalhandler.c) 28 / 38 Weitere Beispiele zu Signalen I Signal bei Ende eines Kindprozesses: sigchld.c (extern) I Redefinition des Handlers im Handler: catch_ctrl_c.c (extern) I Selbstabbruch nach definierter Zeitspanne: alarm.c (extern) 29 / 38 Zwischenfazit: Signale unter POSIX 4 „klassische“ Funktionen: I kill() I signal() I pause() - wartet (passiv) auf ein Signal I alarm() - definiert eine Zeitspanne, bis SIGALRM zugestellt wird („Der Wecker klingelt.“) 30 / 38 Nachteile und Unzulänglichkeiten von Signalen I unzuverlässig I keine Nutzdatenübertragung I keine Priorisierung I keine Speicherung (in Warteschlange) modernere (aber kompliziertere) Signalbehandlung: sigaction(), sigprocmask() & Co. 31 / 38 Gemeinsam genutzter Speicher (Shared Memory) I Idee: Kommunikation über gemeinsamen Speicher I keine implizite Synchronisation (!) I ohne Adressräume problemlos implementierbar bei virtuellem Speicher Funktionen des BS nötig: I I I I I I Anlegen des Segmentes Einblenden in beide Adressräume (Datenübertragung) Ausblenden aus allen Adressräumen Zerstören des Segments I Zugriff auf gemeinsam genutzten Speicher über Zeiger, überlagerte Datenstrukturen (→ effizient), kein Systemruf nötig I UNIX: shmget(), shmat(), shmdt(), shmctl() I Segmente sind i.a. persistent (überleben den anlegenden Prozess) 32 / 38 Nachrichtenaustausch (Message Passing) Prinzip 1. Sender konstruiert Nachricht und trägt diese in einen Puffer ein 2. Sender ruft Funktion send() 3. Nachricht wird durch das System transportiert 4. Empfänger ruft Funktion receive(), der er einen Puffer übergibt, in den die Nachricht kopiert wird Analogie: Briefsendung 33 / 38 Nachrichtenaustausch (Message Passing) Diskussion I notwendig, wenn kein gemeinsamer Speicher existiert (z. B. in verteilten Systemen) I jedoch auch mit gemeinsamem Speicher möglich (z. B. Unix) I zwei grundlegende Operationen: send(), receive() I synchrone und asynchrone Operation möglich Beispiele: I Message Passing Interface (MPI) I Nachrichtenwarteschlangen POSIX (msgrcv(), msgsnd() usw.) 34 / 38 Synchroner und asynchroner Nachrichtenaustausch π1 π1 π2 π2 send() π2 send() Zeit receive() π1 receive() I. send() receive() II. III. Abbildung: I./II. – blockierend, III. nichtblockierend (asynchron) 35 / 38 Kommunikation über Sockets . . . in der LV „Rechnernetze“ 36 / 38 Was haben wir gelernt? 1. Was sind IPC-Mechanismen? 2. ausführlich kennengelernt: I I I Datenaustausch mittels Datei die „klassische“ Unix-Pipe Signale (zumindest in der Bash) 3. kurz angerissen I I Shared Memory Message Passing 4. nicht behandelt I I Sockets named Pipes 37 / 38 Testfragen 1. Beschreiben Sie den Ablauf bei der Zustellung eines Signals! 2. Was ist der Unterschied zwischen synchronem und asynchronem Senden beim Message Passing? 3. Entwerfen Sie ein C-Programm, das einen Sohn erzeugt und diesem mittels einer Pipe eine Nachricht zukommen lässt! 4. Welchen Kommunikationsmechanismus würden Sie einsetzen, wenn Sie Daten übertragen müssen und die Teilnehmer nicht verwandt sind? 5. Was ist ein persistenter Kommunikationsmechanismus? 38 / 38 Vorlesung Betriebssysteme I Thema 7: Zuteilung des Prozessors Robert Baumgartl 27. Januar 2015 1 / 33 Prozessorzuteilung (Scheduling) I = Beantwortung der Frage: „Welche Aktivität soll zu einem bestimmten Zeitpunkt abgearbeitet werden (und für wie lange)?“ I Komponente im Betriebssystem: der Scheduler (Planer) I Verfahren zur Ermittlung einer Abarbeitungsplans (Schedule) 2 / 33 Typische Zielgrößen Je nach betrachteter Systemklasse (z. B. Batchsysteme, Interaktive Systeme, Echtzeitsysteme) existieren verschiedene zu optimierende Parameter: I mittlere Reaktionszeit aller Prozesse I mittlere Verweilzeit aller Prozesse (turnaround time) I maximale CPU-Ausnutzung I maximale Anzahl gleichzeitiger Datenströme I Garantie einer maximalen Reaktionszeit I Fairness: n Prozesse → jeder 1/n der Prozessorzeit I Quality-of-Service (QoS): „Jeder bekommt so viel, wie er bezahlt hat.“ I Ausschluss des Verhungerns einzelner Prozesse 3 / 33 Planung anderer Ressourcen Außer dem Prozessor können (müssen aber nicht) die folgenden Ressourcen geplant werden: I Hauptspeicher, I Aufträge an den Massenspeicher, I Kommunikationsbandbreite, I Interrupts I ... Beispiel: Linux besitzt einen sog. I/O-Scheduler, der Festplattenaufträge plant (d. h. , ggf. umsortiert). 4 / 33 Beispiel: Schedulingebenen in einem Batch-System CPU CPU Scheduler Arriving Job Input Queue Haupt− speicher Admission Scheduler Disk Memory Scheduler Quelle: Andrew Tanenbaum, Modern Operating Systems. 2000, S. 141 5 / 33 Off-Line- vs. On-Line-Verfahren Off-Line I komplette Ermittlung des Abarbeitungsplans vor Inbetriebnahme des Systems I Zur Laufzeit des Systems wird der vorbereitete Plan abgearbeitet (keine Entscheidungen mehr notwendig). I inflexibel I sehr hohe Auslastung möglich I Startzeitpunkte, Ausführungszeiten, Abhängigkeiten aller Aktivitäten müssen a priori bekannt sein. I z. B. bei autonomen oder Echtzeit-Systemen I situationsspezifische Pläne möglich, System unterscheidet mehrere Modi 6 / 33 Off-Line- vs. On-Line-Verfahren On-Line I Auswahl des jeweils nächsten abzuarbeitenden Prozesses erfolgt zur Laufzeit des Systems. I Flexibel: System kann auf Änderungen verschiedener Parameter, Umwelteinflüsse, Nutzeranforderungen reagieren I keine Zeit für langwierige Auswahlverfahren → Kompromiss zwischen Optimalität des ausgesuchten Prozesses und Dauer für die Entscheidung notwendig. Typische interaktive Betriebssysteme wie Windows oder Linux planen on-line. 7 / 33 Beispiel für Off-Line-Scheduling Ein (nicht näher spezifiziertes) Rechensystem bestehe aus 3 Prozessen, die wiederum aus den folgenden unabhängigen Teilprozessen bestehen (benötigte Rechenzeit in Klammern): P1 : { p11 (3), p12 (2), p13 (2), p14 (5) } P2 : { p21 (5), p22 (7) } P3 : { p31 (5), p32 (2) } Außerdem bestehen die folgenden expliziten zeitlichen Abhängigkeiten zwischen den Teilprozessen: p21 vor p12 , p12 vor p22 , p13 vor p31 , p14 vor p32 , p22 vor p32 . Darüberhinaus müssen die Teilprozesse ein- und desselben Prozesses hintereinander liegen. 8 / 33 Präzedenzgraph Die zeitlichen Abhängigkeiten veranschaulicht man am besten in einem Präzedenzgraphen: I einen Knoten für jeden Teilprozess I eine Kante zwischen zwei Knoten genau dann, wenn der erste Knoten beendet sein muss, bevor der zweite gestartet werden darf p11 p14 p13 3 p12 5 2 p31 2 p21 5 p22 5 p32 2 7 Abbildung: Präzedenzgraph des Beispielprozesssystems 9 / 33 Ableitung eines Schedules (off-line) Verfahren: 1. Bildung der Bereit-Menge B (enthält alle Prozesse, die abgearbeitet werden können) 2. Auswahl von n Prozessen aus B (n ist die Prozessoranzahl, im einfachsten Falle also 1) nach vorgegebenem Kriterium (z. B. „den kürzesten Prozess zuerst“) 3. Planung der ausgewählten Prozesse für bestimmte Zeitspanne (im einfachsten Falle: für eine Zeiteinheit) 4. Falls noch nicht alle Prozesse geplant sind → Goto 1 5. Stop 10 / 33 Anwendung auf Beispieltaskmenge I I I n = 2 (z. B. Dualcore-Prozessor) Auswahl des jeweils kürzesten Prozesses (Shortest Job Next) Abarbeitung ohne Unterbrechung, wenn einmal gestartet (Run-to-Completion) Zeit 0 3 5 7 9 14 19 B p11 , p21 (p21 ) p12 p13 , p22 p14 , p31 p31 p32 Auswahl p11 , p21 (p21 ) p12 p13 , p22 p14 p31 p31 Tabelle: Schedulingzeitpunkte für Beispiel 11 / 33 Resultierender Schedule p 11 P1 p 12 0 2 p 31 p 32 p 22 p 21 P2 p 14 p 13 4 6 8 10 12 14 16 18 20 22 Abbildung: Off-Line Schedule für Beispieltaskmenge und ohne Unterbrechungen I Resultat: Gantt-Diagramm (benannt nach dem Unternehmensberater (!) Henry L. Gantt) I Komplettierung des letzten Teilprozesses zu t = 21 I Prozessoren nicht voll ausgelastet (idle time); Ursache: Präzedenzen zwischen Teilprozessen 12 / 33 Zeitgesteuertes Scheduling I alle Abläufe im System erfolgen in festem zeitlichen Rahmen, periodisch I keine Interrupts → keine unvorhergesehenen Aktivitäten I Kommunikation mit externe Komponenten: Abfragen (Polling) I typisch für autonome und Echtzeitsysteme I Nutzung von off-line ermittelten Schedules, zwischen denen umgeschaltet werden kann (Moduswechsel) I Beispiel: Medienzugriffsverfahren Time Division Multiple Access (TDMA) 13 / 33 Time Division Multiple Access Prinzip: I Übertragungszeit wird in (unendlich viele) Perioden fester Länge aufgeteilt I innerhalb jeder Periode erhält jeder (potentielle) Kommunikationsteilnehmer 1/n der Periodenlänge, einen sog. Slot I in seinem Slot kann jeder senden oder nicht I → keine Kollisionen möglich Prozess sendet nicht. ... 0 1 2 3 4 5 6 7 t Slot Periode 14 / 33 Ereignisgesteuertes Scheduling Prinzip: I System reagiert auf Einflüsse von außen (Interrupts) I Aktivitäten werden als Reaktion auf Interrupts bereit I prinzipiell keine Garantie von Ausführungszeiten möglich, da Auftrittszeitpunkte von Interrupts nicht vorhersehbar I typisch für interaktive Systeme I Beispiel: Grafische Benutzeroberflächen (Ereignisse: Mausbewegung, Klick, Tastendruck, aber auch Interrupt durch die Netzwerkkarte) 15 / 33 Was passiert denn eigentlich beim Interrupt? Prozess Instruktion n Instruktion 1 Instruktion n+1 Instruktion 2 Interruptservice− Routine (ISR) Interrupt Instruktion n+2 IRET Abbildung: Ablauf einer Interruptbehandlung (vereinfacht) I Interrupts sind asynchron zum Programmablauf I Quellen: Geräte (I/O), Programm, Betriebssystem 16 / 33 Interrupt: Ablauf in der CPU Hardware Device controller or other system hardware issues an interrupt Processor finishes execution of current instruction Software Save remainder of process state information Process interrupt Processor signals acknowledgment of interrupt Processor pushes PSW and PC onto control stack Processor loads new PC value based on interrupt Restore process state information Restore old PSW and PC (William Stallings: Operating Systems. 6th ed., Pearson, 2009) Figure 1.10 Simple Interrupt Processing 17 / 33 Schedulingzeitpunkt beim On-Line Scheduling Unterbrechung eines aktiven Prozesses: I durch das BS, (prinzipiell) jederzeit (präemptives Multitasking): I I I wenn ein Prozess blockiert (z. B. an Ressource), wenn ein Prozess bereit wird (z. B. als Reaktion auf einen Interrupt oder durch eine Ressourcenfreigabe), wenn ein Prozess endet. I durch das BS, jedoch nur an bestimmten Stellen, sogenannten Preemption Points I freiwillig, an bestimmten Stellen, z. B. Systemruf (kooperatives Multitasking) I nach Komplettierung einer Aktivität (run-to-completion) 18 / 33 Prioritäten und Priorisierung I (gewollt) unfair, Prozesse besitzen unterschiedliche Wichtigkeit I einfachste Möglichkeit: Fixed External Priorities (FEP)) I d. h. , jeder Prozess erhält vor der Laufzeit des Systems einen Parameter fest zugeordnet, der seine Wichtigkeit ausdrückt, seine Priorität I zur Laufzeit wird stets der höchstpriorisierte unter allen bereiten Prozessen ausgewählt 19 / 33 Prioritäten zum zweiten Implizite Prioritäten: ein bestimmter Parameter jedes Prozesses wird „zweckentfremdet“ zur Bestimmung der Priorität herangezogen. Beispiele: I Länge des Jobs I verbleibende Abarbeitungszeit I Zeit seit letzter Aktivierung I Deadline (Zeit bis zur unbedingten Komplettierung) 20 / 33 Statische und dynamische Prioritäten Statisch: Priorität eines Prozesses ist konstant. I einfacher Scheduler I gut zu analysieren I nicht besonders flexibel (was ist, wenn sich die Wichtigkeit eines Prozesses ändert?) Dynamisch: Priorität eines Prozesses ändert sich mit der Zeit. I periodische Neuberechnung (Aufwand!) I erlaubt situationsspezifische Anpassungen I schwieriger zu analysieren 21 / 33 Uniprozessor- vs. Multiprozessor-Scheduling I I zusätzlich nötige Entscheidung, wo Prozess abgearbeitet wird Ziel: Load Balancing I I zu starr: möglicherweise schlechte Ausnutzung der Prozessoren zu flexibel: häufiger Wechsel des Prozessors (Thrashing) → sehr hoher Overhead I ideal: auf einem unbeschäftigten Prozessor fortsetzen I günstig: Prozessor, auf dem der Prozess unterbrochen wurde (Cache, TLB) I Parameter Affinität des Prozesses zu einem bestimmten Prozessor 22 / 33 Round Robin – Zeitscheibenverfahren Idee: Jeder Prozess erhält den Prozessor für eine bestimmte Zeitspanne (Quantum tq ), dann ist der nächste dran. I Grundgedanke: Fairness I tq klein → Umschaltaufwand im Verhältnis zur Nutzarbeit groß, kleine Reaktionszeit pro Prozess I tq groß → relativer Umschaltaufwand klein, Reaktionszeit pro Prozess groß I wichtiger Parameter: Umschaltzeit tcs (Context Switch Time) I Reaktionszeit eines Prozesses abhängig von tcs , Anzahl Prozesse, tq I häufig Kombination mit Prioritäten (RR innerhalb einer Prioritätsklasse) 23 / 33 Veranschaulichung Round-Robin t cs ... P1 P2 P3 P1 ... tq t rsp Abbildung: Parameter beim Zeitscheibenverfahren 24 / 33 Beispiel: Einfache Batch-Verfahren First In First Out (FIFO, FCFS) I Prozesse werden in der Reihenfolge ihres Eintreffens (vollständig abgearbeitet) I fair I leicht zu analysieren (→ Warteschlangentheorie) Shortest Job Next (SJN) I Idee: schnell ein paar kurze Jobs fertigstellen, bevor alle auf einen langen Job warten müssen. I Prozess mit der kürzesten Dauer wird ausgewählt, run-to-completion I Ausführungszeit muss bekannt sein I minimiert mittlere Verweilzeit (t v ) und mittlere Wartezeit (t w ) I ungerecht, Verhungern möglich 25 / 33 Beispiel zu SJN Job J1 J2 J3 J4 4 Beispieltasks: J4 0 J1 3 J3 Dauer 6 8 7 3 J2 9 16 24 Abbildung: Resultierender SJN-Schedule tw = 0 + 3 + 9 + 16 =7 4 tv = 3 + 9 + 16 + 24 = 13 4 26 / 33 Unix I I zeitscheibengesteuert (Quantum) versucht, 2 Klassen von Prozessen zu unterscheiden und getrennt zu behandeln: 1. interaktive („I/O-bound“) 2. (vorwiegend) rechnende („compute-bound“) I Rechnende Prozesse nutzen ihre Zeitscheibe voll aus I Interaktive Prozesse nutzen ihre Zeitscheibe häufig nicht aus (warten auf Interaktion durch Nutzer oder Gerät; d. h. blockieren häufig) wenn Zeitscheibe nicht ausgenutzt, wird Priorität (leicht) erhöht → Unix bevorzugt interaktive Prozesse: I I I interaktive Prozesse reagieren besser rechnende Prozesse werden etwas benachteiligt 27 / 33 Linux? I dynamische Prioritäten mit Zeitscheiben I genaues Verfahren ziemlich kompliziert I jeder interaktive Prozess besitzt einen sog. nice-Value dieser beschreibt, wie der betreffende Prozess im Vergleich zu anderen interaktiven Prozessen priorisiert wird I I I I I -20: höchste Priorität 0: default 19: niedrigste Priorität Kommandos nice und renice (für bereits laufende Prozesse) ändern diesen Wert ~> renice 20 -p 24195 24195: old priority 0, new priority 19 Achtung: normale Nutzer dürfen Priorität nur monoton ändern. 28 / 33 Anzeige Priorität und nice-Wert mittels top top - 14:31:23 up 3:28, 6 users, load average: 1.68, 0.67, 0.30 Tasks: 91 total, 4 running, 87 sleeping, 0 stopped, 0 zombie Cpu(s): 42.1%us, 44.7%sy, 13.2%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 256396k total, 239564k used, 16832k free, 31364k buffers Swap: 1048568k total, 84k used, 1048484k free, 100936k cached PID 3735 24194 24195 23793 23928 1 2 3 4 5 6 9 10 104 138 139 140 USER root robge robge robge robge root root root root root root root root root root root root PR 16 15 39 15 15 15 RT 34 10 10 11 17 19 10 15 15 10 NI 0 0 19 0 0 0 0 19 -5 -5 -5 -5 -5 -5 0 0 -5 VIRT 161m 7404 5672 9640 7408 1948 0 0 0 0 0 0 0 0 0 0 0 RES 12m 3216 2636 5808 3260 648 0 0 0 0 0 0 0 0 0 0 0 SHR 4400 2244 1412 4272 2264 552 0 0 0 0 0 0 0 0 0 0 0 S R S R S R S S S S S S S S S S S S %CPU %MEM 50.9 4.9 26.6 1.3 15.6 1.0 6.0 2.3 0.3 1.3 0.0 0.3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 TIME+ 3:08.68 1:59.25 2:08.29 0:01.57 0:01.82 0:01.14 0:00.00 0:00.00 0:00.08 0:00.00 0:00.00 0:00.00 0:00.00 0:00.02 0:00.01 0:00.08 0:01.04 COMMAND Xorg xterm bash WindowMaker xterm init migration/0 ksoftirqd/0 events/0 khelper kthread kblockd/0 kacpid kseriod pdflush pdflush kswapd0 29 / 33 Scheduling in Windows 2000/XP/Vista I prioritätsgesteuert, präemptiv 31 "real−time" levels 16 15 variable levels 1 0 system level Abbildung: Prioritätsstufen im Windows 2000/XP 30 / 33 Scheduling in Windows 2000/XP/Vista I Round-Robin bei Threads gleicher Priorität I Länge des Quantums differiert für Desktop- und Server-Variante (Server: 6fach länger!) I Quantum wird für Vordergrundthreads verdoppelt temporäre Prioritätsanhebung (Priority Boost) in den Levels 1-15 u. a. bei I I I I Komplettierung einer I/O-Operation Fensterthreads, die in den Vordergrund gelangen, Gefahr des Verhungerns. 31 / 33 Prinzip des Priority Boost tq Priorität Basis− priorität aktiv wartend aktiv preempted aktiv Zeit 32 / 33 Was haben wir gelernt? 1. on-line vs. off-line Scheduling 2. zeitgesteuertes vs. ereignisgesteuertes Scheduling 3. Interrupts 4. kooperatives vs. präemptives Multitasking 5. statische vs. dynamische Prioritäten 6. Round Robin; Einfluss der Zeitscheibenlänge 7. Priority Boost 33 / 33 Vorlesung Betriebssysteme I Thema 8: Threads (Aktivitäten, die zweite) Robert Baumgartl 28. 01. 2014 1 / 22 Threads (Leichtgewichtsprozesse) I I Prozess = Container für Ressourcen + (ein) identifizierbarer Handlungsablauf (“Thread of Execution”) Idee: Trennung beider Konzepte: I I Prozess = Container für Ressourcen (passiv) Thread = identifizierbarer unabhängiger Handlungsablauf (aktiv) I → ein oder mehrere Threads pro Prozess möglich, diese teilen sich die Ressourcen des Prozesses I → parallele Abarbeitung innerhalb eines Adressraums Der Begriff „Thread“ ist auch im Deutschen weitestgehend etabliert, die korrekte Übersetzung „Faden“ benutzen nur Fanatiker. Eher wird noch „Leichtgewichtsprozess“ eingesetzt. 2 / 22 Veranschaulichung mehrerer Threads ... ... ... ... ... ... ... P3 ... ... P2 ... ... ... P1 P1 Abbildung: Übergang von mehreren Prozessen zu mehreren Threads in einem Prozess 3 / 22 Konsequenzen I I I I Thread kann nur innerhalb eines Prozesses existieren! alle Threads eines Prozesses teilen sich dessen Ressourcen und Adressraum bis auf die Register und den Stack ⇒ kein Schutz zwischen Threads eines Prozesses Kooperation im Vordergrund dem Prozess gehörend jedem Thread gehörend Adressraum Globale Variablen eröffnete Dateien Signale Kindprozesse Program Counter Register Stack (!) automatische Variablen Globalzustand Tabelle: Gemeinsame und private Ressourcen von Threads eines Prozesses (Beispiele) 4 / 22 Warum Threads? I I I I I feingranulare Parallelität der Verarbeitung Erzeugung/Vernichtung viel schneller als von Prozessen effektive Ausnutzung mehrerer CPUs/Kerne Umschaltung zwischen Threads eines Prozesses schnell Dekomposition in Threads liefert Performancegewinn, insbesondere wenn Ein-/Ausgabe-beschränkte Funktionalität Abbildung: Textverarbeitung mit 3 Threads (Tanenbaum: Modern Operating Systems, S.95) 5 / 22 Variante 1: User-Level-Threads I I I I I I I Threads werden im User Mode (d.h., ohne Intervention und Wissen des Betriebssystems) erzeugt, synchronisiert, vernichtet Threadbibliothek, die Routinen zum Erzeugen, Beenden, Synchronisieren und Umschalten von Threads realisiert, erforderlich Threadbibliothek übernimmt Management aller Threads (speichert deren Zustandsinformationen) Umschaltungvorgang: Sichern und Restaurieren des Thread-Kontextes (alle Register) kooperatives Programmiermodell: jeder Thread muss freiwillig (ab und zu) den Prozessor abgeben Kernel hat kein Wissen über Threads, kennt (und verwaltet) nur Prozesse m:1-Abbildung, d. h. , allen Threads ist genau eine Kernel-Aktivität zugeordnet, nämlich der zugehörige Prozess 6 / 22 Veranschaulichung von User-Level-Threads ... ... T3 ... T2 ... T1 ... ... P1 ... ... Thread Library User Mode Kernel Mode Abbildung: User-Level-Threads 7 / 22 User-Level-Threads, cont’d Bewertung: + kann (auch) für Betriebssystem implementiert werden, welches kein Threadkonzept kennt (z. B. MS-DOS) + Threadoperationen besonders schnell, da kein Kernein-/austritt, kein Flush der Prozessorcaches, kein Adressraumwechsel – blockierender Systemruf blockiert alle Threads eines Prozesses (verhindert Parallelität), Abhilfe: ? nichtblockierende Systemrufe ? im Vorhinein ermitteln, ob Ruf blockieren wird (z. B. mittels select()); wenn ja, dann Weiterarbeit eines anderen Threads – Page Fault blockiert alle Threads eines Prozesses – kooperatives Programmiermodell mit freiwilliger Abgabe des Prozessors erforderlich (da keine unterbrechende Instanz aka Betriebssystem) 8 / 22 Variante 2: Kernel-Level-Threads I 1:1-Abbildung (jedem Thread ist genau eine Aktivität des Kernels zugeordnet) I Threads im Kernel verwaltet, dieser verteilt Threads auf alle existierenden Kerne I Threadoperationen teurer, da mit Systemruf (~eintritt, ~austritt) verbunden (z. B. CreateThread() in Win32) I Kombinationen aus User-Level- und Kernel-Level-Threads sind ebenfalls möglich 9 / 22 Veranschaulichung von Kernel-Level-Threads ... ... T3 ... T2 ... T1 ... ... P1 User Mode ... ... Kernel Mode CPU Abbildung: Kernel-Level-Threads 10 / 22 Transition single-threaded → multi-threaded Komplexität der Umwandlung traditioneller sequentieller Programme in multithreaded applications darf nicht unterschätzt werden! Einige Problemkreise: I globale Systemvariablen, wie errno stehen nur einmal pro Prozess zur Verfügung I nicht reentranter Code, z. B. in Bibliotheken, muss vor gleichzeitigem Betreten durch mehrere Threads geschützt werden I Signale sind meist prozessspezifisch I Management mehrerer Stacks bei User-Level-Threads 11 / 22 Threads in Windows I Windows-Welt: beginnend ab Windows NT (Win32-API) sind Kernel-Level-Threads im System verankert. I I CreateProcess() legt einen neuen Adressraum an und startet in ihm einen (ersten) Thread mittels CreateThread() können in einem existierenden Prozess weitere Threads gestartet werden I User-Level-Threads existieren zusätzlich: die so genannten Fibers I d. h. , es können mehrere User-Level-Threads (Fibers) in einem Kernel-Level-Thread existieren 12 / 22 Threads in Linux I ab Kernel 2.0 Bibliothek LinuxThreads I weitgehend, aber nicht vollständig, POSIX-kompatibel I limitiert (max. Threadanzahl 8192) I nicht allzu performant I daher ab 2002 Entwicklung der Native POSIX Thread Library (NPTL) I behebt diese Nachteile, voll POSIX-kompatibel I 1:1-Implementierung (1 Thread pro Kernelaktivität) I andere Unixe besitzen u. U. andere Thread-Implementierungen, die aber stets POSIX-Threads realisieren Abfrage der installierten Thread-Version in Linux: ~> getconf GNU_LIBPTHREAD_VERSION 13 / 22 POSIX-Threads (Pthreads) I POSIX standardisiert ein Thread-API für Unix-artige Betriebssysteme I API wird Pthreads genannt I Standard enthält keine Aussage zur Implementierung der Funktionen (z. B., ob Kernel- oder User-Level-Threads realisiert werden sollen) I man 7 pthreads I auch für Win32 verfügbar (pthreads-w32) 14 / 22 Pthreads-API – Übersicht pthread_create() pthread_join() pthread_exit() pthread_detach() pthread_kill() pthread_attr_init() pthread_mutex_lock() pthread_mutex_unlock() pthread_cond_init() pthread_cond_wait() pthread_cond_signal() Anlegen eines neuen Threads Warten auf Ende des Threads Beenden des rufenden Threads Abkoppeln vom Vater Zustellung eines Signals an Thread Init der Thread-Attribute Synchronisation am Mutex Anlegen einer Bedingungsvariable Sync. an Bedingungsvariable Tabelle: Einige Funktionen der Pthreads-API 15 / 22 Pthreads-Programmierung I #include <pthread.h> I Linken mit Schalter -lpthread I Funktionsnamen beginnen stets mit pthread_ I alle Funktionen liefern 0 wenn erfolgreich, -1 bei Fehler I Threads eines Prozesses kommunizieren über gemeinsame (globale) Variable I IPC nur zu Threads anderer Prozesse 16 / 22 Hello, world mittels Pthreads # i n c l u d e < p t h r e a d . h> # i n c l u d e < s t d i o . h> # i n c l u d e < s t d l i b . h> # d e f i n e MAXITER 200000 v o i d ∗ t h r e a d _ f ( v o i d ∗arg ) { p r i n t f ( "world!\n" ) ; p t h r e a d _ e x i t ( NULL ) ; } i n t main ( v o i d ) { pthread_t a ; int ret ; } p r i n t f ( "Hello, " ) ; r e t = pthread_create ( &a , /∗ p o i n t e r t o v a r i a b l e c o n t a i n i n g t h r e a d ID NULL , /∗ p o i n t e r t o t h r e a d a t t r i b u t e s ( v o i d ∗) &t h r e a d _ f , /∗ t h r e a d f u n c t i o n NULL ) ; /∗ p o i n t e r t o argument i f ( r e t != 0) { p e r r o r ( "creating 1st thread" ) ; e x i t ( EXIT_FAILURE ) ; } p t h r e a d _ j o i n ( a , NULL ) ; e x i t ( EXIT_SUCCESS ) ; ∗/ ∗/ ∗/ ∗/ 17 / 22 Erzeugung eines Threads int pthread_create(pthread_t *tid, pthread_attr_t *attr, void* (*start_fkt)(void*), void *arg); I erzeugt neuen Thread I *tid: Identifikator des neuen Threads I *attr: legt Attribute des Threads fest I *start\_fkt: Startfunktion I *arg: Zeiger auf (beliebiges) Datum, welches der Thread als Parameter erhält I keine Vater-Sohn-Beziehungen; jeder darf create-n und join-en 18 / 22 Join und Detach int pthread_join(pthread_t tid, void **ret); I Analogon zum waitpid(), wartet auf Ende des Threads mit Id tid I Rückgabewert über ret I erst nach join() wird der Thread vernichtet (analog Zombie-Status) int pthread_detach(pthread_t tid); I macht den Thread un-join-bar, d.h., er wird sofort vernichtet, wenn er seine Startfunktion verlässt 19 / 22 GNU Portable Threads (GNU Pth) I User-Level-Threads für Unix I m:1-Implementierung I http://www.gnu.org/software/pth/ I kooperatives Multitasking mit Prioritäten I Linken mit Schalter -lpth 20 / 22 Hello, world! mit GNU Pth # i n c l u d e < p t h . h> # i n c l u d e < s t d i o . h> # i n c l u d e < s t d l i b . h> v o i d ∗p t h _ t h r e a d ( v o i d ∗arg ) { p r i n t f ( "world\n" ) ; p t h _ e x i t ( NULL ) ; } i n t main ( v o i d ) { pth_t t i d ; if (! pth_init () ) { p r i n t f ( "No pth lib available\n" ) ; e x i t ( EXIT_FAILURE ) ; } p r i n t f ( "Hello, " ) ; t i d = pth_spawn (PTH_ATTR_DEFAULT, &p t h _ t h r e a d , NULL ) ; if (! tid ) { p r i n t f ( "Could not spawn thread\n" ) ; e x i t ( EXIT_FAILURE ) ; } p t h _ j o i n ( t i d , NULL ) ; } return 0; 21 / 22 Was haben wir gelernt? I Threads sind eine Abstraktion zur effizienten Parallelisierung von Programmabläufen. I Kernel-Level-Threads ↔ User-Level-Threads I Windows bringt beide Arten „von Haus aus“ mit I wichtigste Implementierung unter Unix/Linux: Pthreads I pthread_create() startet einen neuen Thread I pthread_exit() beendet einen Thread (oder: Verlassen der Threadfunktion) 22 / 22