Betriebssysteme 13/14 Prozesse und Threads 2 Oktober 2013 1/72
Was ist ein Prozess? Was ist ein Thread? typischer Bootvorgang Bootloader (Grub,...) Kernel und initramfs Filesysteme, Devices init-prozess Wieso Prozess? Was ist ein Prozess überhaupt? Und wie entsteht er? 2/72
Am Anfang... main_console = new TextConsole ( 4 );... Scheduler :: instance () - > addnewthread ( main_console );... void TextConsole :: Run ( void ) // vereinfacht { } do { getkeyfromkbd ( key ) handlekey ( key ); Scheduler :: instance () - > yield (); } while ( 1 ); // until the end of time 3/72
Programm und Thread Ein Programm ist zuerstmal Code: vielleicht kompilierbar vielleicht lauähig vielleicht fehleranfällig Ein Prozess oder ein Thread ist eine Aktivität: die CPU führt programmierte Befehle aus Besteht aus Programmcode Input Output Zustand 4/72
Mehrere Prozesse oder Threads Eine CPU - zu einem Zeitpunkt ein aktiver Prozess bzw. Thread Wechsel zwischen Threads - wie macht das die CPU? 5/72
Mehrere Prozesse oder Threads Eine CPU - zu einem Zeitpunkt ein aktiver Prozess bzw. Thread Wechsel zwischen Threads - wie macht das die CPU? IP / PC woanders hinsetzen... 6/72
Mehrere Prozesse oder Threads (2) IP / PC woanders hinsetzen... Also so: JMP Thread2 Funktioniert das? 7/72
Mehrere Prozesse oder Threads (2) IP / PC woanders hinsetzen... Also so: JMP Thread2 Funktioniert das? Nein... Wohin genau? Wie zurück? Sicherheitsfragen... Schaun wir uns das mal in SWEB an. 7/72
switch.s (aus SWEB) mov ebx, dword [ currentthreadinfo ]... push dword [ ebx + 8] ; push eflags push dword [ ebx + 4] ; push cs push dword [ ebx + 0] ; push eip push dword [ ebx + 24] pop ebx ; restore ebx iretd ; switch to next Was passiert hier? 8/72
Switch currentthreadinfo gesetzt in schedule.cpp Datenstruktur mit Menge von Registern, die den Zustand der CPU zu einem vergangenen Zeitpunkt widerspiegeln Wieso iretd? 9/72
was macht IRETD? IRETD - Interrupt Return Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software generated interrupt. komplexe Instruktion vereinfachte Darstellung: EIP <-- Pop(); CS <-- Pop(); EFLAGS <-- Pop(); 10/72
was macht IRETD? push dword [ ebx + 8] ; push eflags push dword [ ebx + 4] ; push cs push dword [ ebx + 0] ; push eip IRETD 11/72
was macht IRETD? push dword [ ebx + 8] ; push eflags push dword [ ebx + 4] ; push cs push dword [ ebx + 0] ; push eip EIP <-- Pop () ; CS <-- Pop () ; EFLAGS <-- Pop () ; 12/72
was macht IRETD? push dword[ebx + 8] ;push eflags push dword[ebx + 4] ;push cs push dword[ebx + 0] ;push eip EIP <-- Pop(); CS <-- Pop(); EFLAGS <-- Pop(); 13/72
Wieso Interrupt Return wenn wir doch nur zu einem neuen Thread wechseln wollen... CPU beherrscht viele nützliche Instruktionen manche davon haben - bei falscher Anwendung - unangenehme Nebenwirkungen z.b. CLI - Clear Interrupt Flag keine externen Interrupts mehr akzeptiert gefährlich! Anwenderprogramme sollen diese Instruktionen nicht ausführen dürfen 14/72
Privileged Instructions - Intel LGDT Load GDT register LLDT Load LDT register LTR Load task register LIDT Load IDT register MOV (control registers) Load and store control registers. LMSW Load machine status word. CLTS Clear task-switched ag in register CR0 MOV (debug registers) Load and store debug registers INVD Invalidate cache, without writeback WBINVD Invalidate cache, with writeback INVLPG Invalidate TLB entry HLT Halt processor RDMSR Read Model-Specic Registers WRMSR Write Model-Specic Registers RDPMC Read Performance-Monitoring Counter RDTSC Read Time-Stamp Counter. 15/72
User und Kernel Mode Wir unterscheiden unterschiedliche Privilege-Ebenen User Mode Kernel (oder supervisor) Mode Arbeitsmodus der CPU Manche CPUs: 2 Ebenen (MIPS) andere mehrere (Intel) 16/72
IA32 - Ringe 17/72
Ringwechsel Wechsel von Ring 3 auf Ring 0 muss überwacht werden Kontrollierter Übergang System Calls Intel: INT 0x80 oder SYSENTER/SYSCALL Unterschied: Geschwindigkeit In Sweb: INT 0x80 18/72
Wieso Interrupt Return 19/72
Wieso Interrupt Return 20/72
Wieso Interrupt Return 21/72
Wieso Interrupt Return 22/72
Wieso Interrupt Return Wechsel in Kernel-mode ursprünglich über Interrupt Instruktionsadresse über Tupel CS (Code Segment Selector) und EIP (Instruction Pointer) referenziert Rücksetzen des Zustandes des Prozessors (EFLAGS) wesentlich Gleichzeitiges Setzen von CS und EIP nötig IRET macht die Dinge in einem Schritt... (POP EIP; POP CS; POP EFLAGS) 23/72
Switch.s (aus SWEB) mov ebx, dword [ currentthreadinfo ]... push dword [ ebx + 8] ; push eflags push dword [ ebx + 4] ; push cs push dword [ ebx + 0] ; push eip push dword [ ebx + 24] pop ebx ; restore ebx iretd ; switch to next... das ist also der Kern des Wechsels zwischen zwei threads... 24/72
Threads Etwas vereinfacht: Wechsel zwischen threads durch Laden neuer Werte in CS/EIP thread A läuft bedeutet, CPU führt Code von thread A aus kernel läuft bedeutet, CPU führt Code vom kernel aus virtuell - threads sind ein Konzept, dass es uns erleichtert, uns Abläufe vorzustellen, diese zu steuern und zu programmieren CPU muss wenig bis nichts über threads wissen 25/72
Tasks (IA32) Threads auch ohne speziellen CPU-Support implementierbar CPU-support erleichternd IA32: Tasks unit of work that a processor can dispatch, execute, and suspend. task besteht aus execution space code segment stack segment (für jeden priviliege level eines) ein oder mehrere data segments task state segment (TSS) In SWEB nicht extensiv genutzt... 26/72
TSS 27/72
TSS 28/72
Thread, Prozess Thread benötigt genau das, was im TSS steht zwei Threads, die zusammenarbeiten: gleichen Speicher, unterschiedliche Statusinformationen / Stacks / Register... 29/72
Thread, Prozess einer oder mehrere zusammengehörige Threads und deren Ressourcen: Prozess typisch: Programm wird gestartet, nur ein thread aktiv Programm startet weitere threads nach Bedarf 30/72
Wann entsteht ein Prozess? BS muss sicherstellen, dass alle wichtigen Prozesse existieren. Manchmal: alle Prozesse die jemals benötigt werden beim Startup erzeugt Im allgemeinen: Möglichkeit zur Erzeugung / Beendigung erforderlich Wichtigste Ereignisse, die Prozess- Erzeugung veranlassen 1 System-Initialisierung (boot) 2 Ausführung eines process creation system calls 3 Benutzeranforderung 4 Start eines Batch-Jobs 31/72
Booten Mehrere Prozesse werden gestartet Prozesse zur Interaktion mit Anwender Prozesse für bestimmte Funktionen Email-service Drucker-Warteschlange Firewall 32/72
Prozesserzeugung Auch später... Technisch: Immer ein systemcall Unix: fork Windows: CreateProcess SWEB: existiert noch nicht (dann aber: fork) Beide Prozesse separaten Adressraum Bei Unix: vorerst exakte Kopie Bei Windows: von Beginn getrennt 33/72
fork - exec Unix / Linux / SWEB pid_t fork(void) Rückgabewerte: 0 an den neu gestarteten Prozess (child) Prozess-ID an den aufrufenden Prozess (parent) Jetzt laufen zwei beinahe idente Kopien desselben Programmes Unterschied nur im Rückgabewert 34/72
fork - exec Über den Rückgabewert unterscheidbar: bin ich der Vater oder das Kind Kindprozess überlagert seinen Speicher jetzt mit Code des neuen, zu startenden Programmes pid_t childpid ; childpid = fork (); if ( childpid < 0) { // Fehler bei fork } else if ( childpid == 0) { // ich bin das Kind, mach ein exec if ( execv (...)) { // execv fehlgeschlagen } } else { // ich bin der Parent, tu was immer nötig ist } 35/72
Prozess Terminierung Normal exit(freiwillig) Error exit (freiwillig) Fatal error (unfreiwillig) Killed by another process (unfreiwillig) 36/72
Process Hierarchies Parent erzeugt einen child process, die können wieder Prozesse erzeugen Bildet Hierarchie die können wieder Prozesse erzeugen... UNIX nennt das "process group" Windows kennt keine Hierarchie Alle Prozesse sind gleich 37/72
Process Hierarchies A forkt B,C B forkt D,E,F C forkt G D forkt H Abbildung: Prozesshierarchien 38/72
Prozesszustände Grep muster *.c sort Sort muss eventuell auf input warten Blockieren sinnvoll 39/72
Prozesszustände 40/72
Prozesszustände 41/72
Prozesszustände 42/72
Prozesszustände 43/72
Prozesszustände 44/72
Prozesszustände 45/72
Prozesszustände 46/72
Threads Traditionelles Modell: Prozess hat einen Adressraum einen Ausführungsfaden Manchmal wünschenswert, mehrere Ausführungsfäden parallel zu haben wie eigene Prozesse, aber gemeinsamer Adressraum 47/72
Threads Prozess ist Verwaltungseinheit - bündelt zusammengehörige Ressourcen. Ressourcen: Adressraum Oene Files Child Processes Accounting... 48/72
Threads Prozess besitzt einen Ausführungsfaden (thread) Threads: werden für die Ausführung auf CPU verwaltet besitzen: Befehlszähler (PC) Register Stack 49/72
Threads Erlaubt es, mehrere Fäden innerhalb eines Prozesses laufen zu lassen Hohe Unabhängigkeit Leichtgewichtige Prozesse (lightweight processes) Multithreading 50/72
Threads Weniger unabhängig als Prozesse Zugri auf Speicher der anderen Threads! Kein Schutz voreinander! Sollen kooperieren, nicht kämpfen! Zustände: ähnlich wie bei Prozessen - Ready Running Blocked Terminiert 51/72
Multithreading Üblich: zuerst nur ein Thread Startet weitere threads (z.b.pthread_create(...)) Manchmal hierarchisch, manchmal ach Wenn thread fertig: pthread_exit Warten auf thread-ende: pthread_wait CPU freiwillig hergeben: pthread_yield 52/72
Thread - Probleme Entstehen leicht durch die gemeinsamen Datenbereiche Gleichzeitiger Zugri auf gemeinsamen Speicher? Thread schlieÿt File, von dem ein anderer noch liest? Synchronisation! 53/72
Fork-Problem Prozess hat >1 thread Ein Thread eines Prozesses macht fork Neuer Prozess: auch mehrere threads? Wenn ja: Ein thread ist blockiert und wartet auf I/O was macht dieser thread im neuen Prozess? Design-Entscheidungen! Für KU - abzuraten, mehr als einen Thread zu haben! 54/72
Warum überhaupt threads Oft sollen Dinge parallel ablaufen Manche der Dinge blockieren Threads erzeugen einfacheres Programmiermodell Eigentlich dasselbe Argument wie für Prozesse Aber: threads haben Daten gemeinsam Ermöglicht Lösungen, die mit Prozessen nicht möglich oder nicht einfach wären 55/72
Warum überhaupt threads Weniger Ressourcen: einfacher zu Erzeugen und Zerstören Wechsel zwischen Threads eines Prozesses schneller als zwischen Prozessen Performancegewinn möglich Nicht wenn alle CPU-lastig Mehrprozessormaschinen 56/72
Beispiele Textverarbeitung Benutzereingabe Bildschirmanzeige Formattierung Rechtschreibprüfung Autosave Keine Chance mit mehreren Prozessen! 57/72
Beispiel Webserver Sammlung von sequentiellen threads Alle sehr einfach 58/72
Beispiel while ( TRUE ) { get_next_request (& buf ); handoff_work (& buf ); } while ( TRUE ) { wait_for_work (& buf ); look_for_page_in_cache (& buf,& page )); if ( page_not_in_cache (& page )) read_page_from_disk (& buf,& page ); return_page (& page ); } 59/72
Alternative Ein Thread Muss File von Platte lesen Prozess wird blockiert Schlechtere Performance Mögliche Alternative: Non-blocking read 60/72
Non-blocking read while ( TRUE ) { // sehr schematische Darstellung!! get_next_event (& buf ); if is_request_event (& buf ) { if ( page_not_in_cache (& page )) request_page_from_disk (& buf,& page ); save_request_in_table (& buf ); } else { return_page (& page ); } } else if is_disk_event (& buf ) { find_request_in_table ; mark_request_as_done ; return_page (& page ); // no error handling e. g. } else if is_... } 61/72
Non-blocking read Kein sequentieller Prozess mehr Finite-state-machine! Eigentlich werden threads simuliert! Daher: gleich threads! 62/72
Implementierung Zwei Möglichkeiten: Im User-Space Im Kernel (eventuell auch Hybrid) 63/72
User-Space threads Kernel weiÿ nichts von Threads - für Kernel nur ein Prozess Kann in allen BS realisiert werden, auch wenn sie keinen thread- support haben. Früher waren das alle... 64/72
User-Space threads 65/72
User-Space threads Thread table pro Prozess Analog zur Prozess-Tabelle im Kernel Von User-Mode-Runtime-System verwaltet Wenn Thread Funktion ausführt, die den Prozess blockieren könnte_ Aufruf einer Routine im Runtime-System Routine prüft: wird Thread blockieren? Ja: Sichern der Register in Thread-Table Anderen Thread im Zustand ready suchen, Register mit dessen Werten laden. SP und PC wechseln neuer thread ist aktiv Thread-switch auf diese Art: sehr schnell! 66/72
User-Space threads Vorteile: Kein Systemcall nötig Daher sehr schnell Kein context-switch memory-cache ush unnötig etc. Eigenes Scheduling verwendbar Nachteile Thread darf keine System-Calls machen könnte blockiert werden 67/72
User-Space threads : Lösungsmöglichkeit: Alle system-calls non-blocking Änderungen am BS nicht attraktiv Soll ja mit bestehenden BS arbeiten... Auch Auswirkungen auf Userprogramme Manchmal feststellbar ob Call blockiert Select-Systemcall Vor read: select (in library-routine) Wenn read blockieren würde: anderen thread wählen, und dann später wieder nachschauen Inezient und wenig elegant. 68/72
Andere Probleme Page-faults Nicht das gesamte Programm im Speicher Wenn nicht geladene Speicheradresse referenziert wird: page fault BS holt fehlenden Bereich von Platte Prozess: blockiert! (nicht nur thread!) Wenn Thread CPU nicht hergibt... Keine Chance gegen Bösewichte! 69/72
Kernel-Mode threads Kein runtime-system mehr Thread-Table im Kernel Infos wie vorher Tabelle Teil des Prozesstabelleneintrags Thread-Erzeugung etc. system-call Hauptnachteil: Aufwand für Systemcalls viel höher als vorher Thread-recycling 70/72
Kernel-Space threads 71/72
Hyrbride 72/72