Institut für Technische Informatik und Kommunikationsnetze Technische Informatik II Übung 1: Prozesse und Threads Aufgabe 1: Prozesse und Threads a) Wie verhält sich eine Applikation die aus mehreren Prozessen bzw. aus mehreren Userspace- Threads besteht bei einem blockieren Diskzugriff? Bei einem blockieren Diskzugriff wird der ganze Prozess angehalten und somit auch alle seine Threads. Anders als die Applikation mit mehreren Prozessen, wird die multithreaded Applikation also blockieren. b) Welche der folgen Ressourcen werden von allen Threads eines Prozesses geteilt und welche bestehen pro Thread? Program-Counter, Heap-Speicher, globale Variablen, Stack, CPU-Register, geöffnete Dateien, Accounting- und Benutzer-Informationen. Pro Thread: Program-Counter, Stack und CPU-Register. Aufgabe 2: Scheduling a) Was versteht man unter Langzeit-Scheduling (Job-Scheduling), was unter Kurzzeit-Scheduling (CPU-Scheduling)? Der CPU-Scheduler wählt den als nächstes auszuführen Prozess aus der Ready-Queue aus, der Job-Scheduler bestimmt welche Prozesse in den Speicher geladen und welche ausgelagert werden. Desweiteren wird Der CPU-Scheduler aktiv, wann immer ein anderer Prozess zum Zug kommen soll, der Job-Scheduler hingegen wird nur ausgeführt wenn ein Prozess terminiert oder zu wenig Speicher zur Verfügung steht. b) Warum ist es für den Scheduler sinnvoll zwischen I/O-bound und CPU-bound Prozessen zu unterscheiden? I/O-bound Programme sind die meiste Zeit mit der Ein- und Ausgabe von Daten beschäftigt. Sie brauchen ihre Zeitscheibe meist nicht auf sondern blockieren vor deren Ablauf und belasten die CPU kaum. CPU-bound Programme andererseits belasten die CPU sehr stark und beanspruchen ihre Zeitscheibe meist komplett. c) Was sind die Vor- und Nachteile von preemptiv gegenüber non-preemptiv Multitasking. Die Hauptvorteile des preemtiv Multitasking sind, dass ein einzelner Prozess das System nicht blockieren kann und dass die Zuordnung der Prozesszeit besser gesteuert werden kann (priorisierung einzelner Prozesse ist möglich). Ein Nachteil ist zum Beispiel der grössere Aufwand für die Synchronisation der Prozesse und den Schutz von kritischen Abschnitten.
d) Gegeben seien die folgen Prozesse die alle zur Zeit t = 0 erstellt und gestartet werden. Prozess A B C D E Priorität 2. 5. 3. 1. 4. Bedienzeit 100 10 20 10 50 Berechnen Sie für die unten aufgeführten Scheduling-Algorithmen die mittlere Antwortzeit (Responsetime) RT und die Ausführungszeit (Turnaround Time) T T und stellen Sie den Ablauf grafisch dar. First Come First Server (FCFS) RT = (0 + 100 + 110 + 130 + 140)/5 = 96 TT = (100 + 110 + 130 + 140 + 190)/5 = 134 Shortest Job First (SJF) RT = (0 + 10 + 20 + 40 + 90)/5 = 32 TT = (10 + 20 + 40 + 90 + 190)/5 = 70 Priority Scheduling (PS) RT = (0 + 10 + 110 + 130 + 180)/5 = 86 TT = (10 + 110 + 130 + 180 + 190)/5 = 124 Round Robin (RR) mit einer Zeitscheibe von 5 RT = (0 + 5 + 10 + 15 + 20)/5 = 10 TT = (190 + 35 + 75 + 45 + 140)/5 = 97 2
Aufgabe 3: Prozess Synchronisation, Deadlock und Starvation a) Erörtern Sie die Begriffe Race Condition anhand des folgen Beispiels und markieren sie alle Critical Sections. Was für Probleme können bei der Ausführung auf mehreren Prozessen auftreten und wie können diese (z.b. mit Hilfe von Semaphoren oder Monitoren) behoben werden? global const buf_size := 10 global var buf[buf_size] global var num := 0 function boolean push(a) if (num < buf_size) buf[num] := a num := num + 1 return true return false function pop() if (num > 0) num := num - 1 return buf[num] return null Critical Section Abschnitt eines Programms in dem eine beliebige Unterbrechung zu ungewollten Effekten führen kann. Im obigen Beispiel sind dies die beiden Funktionen push() und pop(). Race Condition Konstellationen in denen das Ergebnis einer Operation vom zeitlichen Verhalten bestimmter Einzeloperationen abhängt. Im obigen Beispiel kann es z.b. sein, dass zwei Prozesse scheinbar gleichzeitig etwas auf den Stack legen, aber nur der zuletzt geschriebene Wert erhalten bleibt. Prozess A buf[num] := a num := num + 1 Prozess B buf[num] := a num := num + 1 b) Beschreiben Sie mit Hilfe von Pseudocode die atomaren Operationen TestAndSet, Swap und FetchAndAdd. atomar function TestAndSet(a, b, c) if (a == b) a := c return true 3
return false atomar procedure Swap(a,b) var t := a a := b b := t atomar function FetchAndAdd(a) var t := a a := t + 1 return t c) Gegeben sei die folge atomare Instruktion: atomar function TestAndAdd(a, b, c) if (a == b) a := a + c return true return false Zeigen Sie wie mit deren Hilfe eine binäre Semaphore implementiert werden kann. global var s := 1 procedure P() while (not TestAndAdd(s, 1, -1)) do procedure V() TestAndAdd(s, 0, 1) d) Eine einfache Lösung des Dining-Philosophers-Problem besteht darin, dass einer der Philosophen die Gabeln in der umgekehrten Reihenfolge aufnimmt als alle anderen. Zeigen Sie, dass diese Lösung deadlockfrei ist, in dem Sie angeben welche Deadlock-Voraussetzung(en) nicht erfüllt ist/sind. Ist die Lösung auch gerecht, das heisst starvationfrei? Die Bedingung Circular Wait ist nicht erfüllt. Die Lösung ist nicht starvationfrei; es ist nicht garantiert, dass die Gabel eines Philosophen nicht dauernd von dessen Nachbarn beansprucht wird, wenn dieser darauf zugreifen will. 4
Aufgabe 4: Prozess Synchronisation, Deadlock und Starvation Gegeben sei ein Programm aus drei Prozessen (P1, P2, P3), die ein Haus zeichnen sollen (siehe unten). Es kommt kooperatives Multitasking zum Einsatz. Prozesswechsel passieren nur in der down() Funktion und nur, falls der laufe Prozess warten müsste. Dazu können folge Operationen ausgeführt werden: (A) draw(dx, dy) (B) move(x, y) Wobei draw eine Linie relativ zur aktuellen Position zeichnet und move den Zeichenkopf zur angegebenen Position bewegt, aber nichts zeichnet. Die Ausführung einer Operation dauert eine Sekunde. Es sind folge Operationen implementiert: (A1) draw(0, 2) (B1) move(2, 0) (A2) draw(-2, 0) (A3) draw(2, -2) (A4) draw(-2, -2) A3 (A5) draw(1, 1) A1 (A6) draw(1, -1) A2 A4 A5 A6 y 3 2 1 0 0 1 2 x Das Programm ist unten abgebildet. Eine Programmzeile ist durch ihre Zeilennummer und durch die entspreche Operation gekennzeichnet. Init: 100 (B1) 101 semaphore S1=0 102 start(p1, P2, P3) P1: P2: P3: 200 down(s1) 300 down(s1) 400 down(s1) 205 (A1) 305 (A1) 405 (A5) 210 (A4) 310 (A2) 410 (A6) 215 (A3) 315 up(s1) 415 (A2) 220 up(s1) 420 up(s1) 1. An welcher Koordinate befindet sich der Zeichenkopf 20 Sekunden nachdem das Programm gestartet wurde? An der Koordinate (2,0) 5
2. Passen Sie den Gebrauch der Semaphore im obigen Programm so an, dass ein korrektes Haus gezeichnet wird. Verwen Sie genau drei Semaphore und vergessen Sie nicht, die Semaphore zu initialisieren. Init: 100 (B1) 101 semaphore S1=0, S2=0, S3=0 P1: P2: P3: 200 300 down(s1) 400 down(s3) 205 (A1) 305 (A1) 405 (A5) 207 307 up(s3) 407 208 308 down(s1) 408 210 (A4) 310 (A2) 410 (A6) 212 up(s1) 312 412 213 down(s2) 313 413 215 (A3) 315 415 (A2) 217 up(s1) 317 417 up(s2) 3. Das Programm wird auf einem Rechner ausgeführt wo Priority Scheduling verwet wird. Prozess P1 hat die höchste Priorität und P3 die kleinste (P(P1) > P(P2) > P(P3)). (Prozesswechsel passieren nach wie vor nur in der down() Funktion). i) Wie viele Semaphore werden jetzt mindestens gebraucht, damit das Programm korrekt funktioniert? 1 Semaphor ii) Passen Sie den Gebrauch der Semaphore so an, dass mit der minimalen Anzahl Semaphore deterministisch ein korrektes Haus gezeichnet wird. Init: 100 (B1) 101 semaphore S1=0 P1: P2: P3: 200 300 400 205 (A1) 305 (A1) 405 (A5) 208 308 down(s1) 408 210 (A4) 310 (A2) 410 (A6) 212 down(s1) 312 412 215 (A3) 315 415 (A2) 218 up(s1) 418 up(s1) 6