Sie sind auf Seite 1von 8

1. Was ist ein Prozess? (Wie unterscheidet er sich von einem Thread?)

Ein Prozess ist ein Programm in Ausführung. Ein Prozess hat einen eigenen Adressraum:

Text

Data

- der Programmcode ! - die Daten !

Stack - temporäre daten!

(Ein Thread hingegen hat zwar einen eigenen Programm-Counter und Stack, allerdings eine gemeinsame Umgebung mit dem Prozess zu dem er gehört: Adressraum, offene Dateien, …)!

2.

Wie werden Prozesse erzeugt?

Der Ursprungsprozess (Proc 0) namens Init wird von Hand erzeugt. !

1. Neue Prozesse sind Kindprozesse und werden per fork() erstellt. Kindprozesse sind eine logische Kopie des Vaters. Gleich sind also:!

 

Adressraum (Text, Daten, Stack) !

Offene Dateien !

Umgebungsvariablen !

Pipes !

 

!

2. Ausführen eines anderen Programms durch das Kind per: exec() (eigentlich: execve()) !

 

Austausch des Adressraums des Kindes !

Starten des angegebenen Programms !

3.

Wie unterscheiden sich Vater- und Kindprozess voneinander? / Woher weiß das Kind, das es ein Kind ist?

Unterscheidbar sind Kind und Vater an der Prozess-ID, d.h. nur daran dass fork() unterschiedliche Ints gibt: 0 beim Kind, ProzessID vom kind beim Vater!

main() {

int pid; pid = fork(); if (pid == 0) {

Kind } else { Vater

}

}

4. Wie werden mehrere Prozesse in einer Einprozessormaschine verwaltet?

Es braucht einen Scheduler um quasi-Parallelität zu „simulieren“ !

Der Scheduler Teilt Prozessor für gewisse Zeitfenster zu !

Es gibt eine Liste der lauffähigen Prozesse: Die Run-Queue !

Und eine Liste der wartenden Prozesse: Die Sleep-Queue !

Gewartet wird hier auf sogenannten „Waitingchannels“ auf bestimmte Ereignisse, die den Prozess wieder lauffähig machen!

5. Was ist Parallelität, was Nebenläufigkeit?

Paralelität !

Die Anweisungen zweier Prozesse werden parallel bearbeitet, wenn die Anweisungen unabhängig voneinander zur gleichen Zeit ausgeführt werden.!

parallele Bearbeitung nur auf Multiprozessorsystemen !

Nebenläufigkeit!

Zwei Prozesse heißen nebenläufig, wenn ihre Anweisungen unabhängig voneinander abgearbeitet werden. Dabei spielt es keine Rolle, ob die Anweisungen zeitlich durchmischt oder auch echt gleichzeitg bearbeitet werden.!

6. Wie geht Round-Robin, wie kann man darin Prioritäten „simulieren"?

!

Funktionsweise !

Run-Queue wird der Reihe nach abgearbeitet!

Darf die CPU nur für eine bestimmte Zeit behalten !

Dann wird er wieder hinten eingereiht in der Run-Queue !

Prioritäten-Simulation !

Unterschiedlich lange Zeitscheiben !

Mehrfaches Einhängen in die Run-Queue !

7. Woher weiß ein Prozess, dass seine Zeitscheibe vorbei ist?

Nach Ablauf der Zeitscheibe (x Clock ticks) findet ein Interrupt statt. !

8. Trap vs. Interrupt

Trap: Ein Trap ist eine Unterbrechung des Prozesses aus prozessinternen Gründen, normalerweise um einen Systemaufruf (also eine Betriebssystemfunktion wie bspw. das Lesen einer Datei) zu starten. Aber auch: Divison durch 0, Zugriff auf illegale Adresse (führt in der Regel zu Programmabbruch), Pagefault!

Der Systemzustand wird gespeichert!

die Kernelanfrage wird ausgeführt!

das Ergebnis wird an den Prozess vermittelt!

Systemzustand und Kontext wird wiederhergestellt, Prozess läuft weiter!

Interrupt: Ein Interrupt ist eine prozessexterne Unterbrechung des Prozesses, z.B. um ein Hardwaresignal zu verarbeiten oder um einen anderen Prozess zum Zuge kommen zu lassen.!

9. Welche Scheduling-Strategie empfiehlst du mir? Was wird bei UNIX- Systemen genutzt?

In Unix !

I. Abgabe der CPU nach Ablauf der Zeitscheibe !

A. Einstellbare Basispriorität!

B. CPU-Nutzung in jüngster Zeit wird einbezogen !

2.

Konto wird mit der Zeit wieder reduziert um langlebige Prozesse nicht zu

benachteiligen !

II. Abgabe der CPU bei Warten auf Ereignis !

A. Ereignis auf das gewartet wird bestimmt Priorität !

B. Betriebsmittel sollen u.U. möglichst schnell wieder freigegeben werden !

Kleinerer Wert = höhere Priorität !

10. Was ist Paging und warum macht man das? Wann tritt ein Pagefault auf und was passiert dann?

Intention ! Die Beschränktheit des tatsächlich vorhandenen physischen Speicher durch einen virtuellen Speicher kompensieren; einen größeren Adressraum zur Verfügung stellen. !

Funktionsweise !

 

Hauptspeicher wird in Kacheln (Page Frames) fester Größe eingeteilt!

Prozessadressräume in Seiten (Pages) gleicher Größe eingeteilt !

letzte Seite muss nicht voll sein: „Interne Fragmentierung“ !

Adressumsetzung über Page-Tabelle (Unterstützt durch Hardware: Memory Management Unit (MMU))!

 

Befindet sich eine Adresse auf einer Seite, die nicht im physikalischen Speicher liegt, kommt es zu einem sogenannten Page-Fault !

Betriebssystem lädt dann die entsprechende Seite aus dem Hintergrundspeicher (i.d.R. die Festplatte) in den Hauptspeicher (dazu wird ein Trap ausgelöst) !

 

11. Was gibt es für Verdrängungsalgorithmen beim Paging und wie funktionieren sie etwa?

Ziel! Zukunftsprognosen darüber welche Pages im Hauptspeicher bleiben sollten anhand der Devise:

„Was bisher galt, wird sich demnächst nicht wesentlich ändern“ (Entspricht dem Lokalitätsprinzip von Prozessen) !

Methodenkategorien !

Verdrängung nach Bedarf !

Durch Pagefault getriggert !

Bereitstellung einer Freispeicherreserve (macht Pagefault schneller behandelbar) !

Verdrängung, sobald Minimalreserve unterschritten !

Methoden im einzelnen !

First in First out (FIFO) !

Entfernt älteste Seiten zuerst!

Problem: Wenig brauchbar, da z.B. Daten-/Stack-Pages immer wieder gebraucht werden !

Least-Frequently-Used (LFU) !

Je seltener benutzt, desto wahrscheinlicher das unwichtig !

Problem: Zu aufwendig da Zugriffszähle geführt werden muss, der selbst Speicherzugriffe erzeugt.!

Außerdem: Annahme oft nicht stimmig: Pages die vor langer Zeit häufig benutzt wurden, bleiben im Hauptspeicher und frisch geladene Seiten werden entfernt!

Umsetzbarkeit: Nur mit Hardwareunterstützung und einem Veralterungskonzept (Aging) !

Least-Recently-Used (LRU) !

Je länger nicht genutzt, desto wahrscheinlicher das es unwichtig wird !

Entfernt Seiten auf die am längsten nicht zugegriffen wurde !

Bewertung: Lokalitätsprinzip i.d.R. gut erfasst. Gute Approximation an Optimum, aber:!

Erfordert Erfassung der Zugriffszeiten (weitere Speicherzugriffe) !

Ohne Spezialhardware zu aufwendig (solche Hardware ist selten) !

Neues Ziel also: Approximation von LRU !

Not-Recently-Used (NRU) !

Beim Zugriff Referenzbit (R) setzen (Hardwareunterstützung / weitere Optimierung nötig) !

Alterungsprozess: Zurücksetzen des R Bits (z.B. periodisch)!

Verdrängung: Seite auswählen, deren R-Bit nicht gesetzt ist !

Clock-Hand-Algorithmus [Wird in Unix genutzt]!

Variante von NRU, die Freispeicherreserve aufbaut !

Nicht gekoppelt an Page-Faults !

Zyklisch untersuchender Urzeiger geht über der Frames im Hauptspeicher !

Ist das R-Bit 0 raus, sonst zurücksetzen und weitersuchen !

Erweiterung: Two-Handed-Clock: Zweiter Zeiger mit festem Abstand: Erster zeiger setzt R-Bits zurück, zweiter wirft raus, falls noch nicht wieder referenziert !

12. Was ist Segmentierung und warum macht man das?

(enthält Zeug aus der Wikipedia) !

Adressraum soll "logisch" gegliedert werden: Text-, Data-, Stack-Segmente !

Schutz dieser Bereiche (z.B.: Daten können nicht als Code interpretiert werden)!

Abbildung des virtuellen Adressraums auf den realen Speicher !

Textsegment bleibt unverändert, Stack & Datensegment können sich verändern !

malloc() fordert zusammenhängenden Speicher an. Intern können 3 Strategien unterschieden werden:!

First Fit (Am Anfang der Freispeicherliste viele kleine Blöcke, Suche Zeitaufwändig)!

Next Fit (erst schnell, dann schnelles zerhacken großer Blöcke)!

Beste Fit (Gut aber Zeitaufwändig, Außerdem: viele extrem kleine Blöcke) !

Wie kleinere Blöcke wieder verschmelzen? ! Buddy Algorithmus:!

Alle Blöcke Größe 2^k !

Segmentierung hat das Problem der externen Fragmentierung!

13. Welche Probleme entstehen bei Nebenläufigkeit, wenn bspw. zwei Threads die Variable i inkrementieren möchten und was verursacht dies? Wie heißt dieses Problem genau? Wie kann man dies mit Semaphoren lösen?

Beide threads werden (in C) den befehl i++ aufrufen. auf maschinenebene wird der befehl jedoch auf 3 befehle aufgespalten. !

1. das Lesen der variable i, !

2. das Hinzuaddieren von 1 !

3. das Speichern des neuen Werts der Variablen i !

Nun kann es passieren, das der erste Tread den Wert von i liest und danach die Zeitscheibe abgeben muss. Nun kommt der zweite Thread, liest i, erhöht den Wert um eins und schreibt den neuen Wert. Dann kommt der erste Thread wieder dran und erhöht den alten Wert von i um eins und überschriebt die Änderung von dem zweiten Thread.!

Was realisiert werden muss ist ein gegenseitiger Ausschluß:! Sema s(1);!

thread 1&2:!

s.P();!

i++;!

s.V();!

dadurch kann nur ein Thread den kritischen Abschnitt betreten !

14. (Was bedeuten die Begriffe: Verhungern, Verklemmung (Deadlock), "After-you-after-you"-Problem?)

Verhungern (Scheduling): ! Ein Thread oder Prozess „verhungert“ wenn er vom Scheduler aus welchen Gründen auch immer dauerhaft nicht die benötigten Betriebsmittel zugeteilt bekommt um seine Aufgabe zu erledigen. !

Verklemmung (Scheduling): ! Zusammenfassung !

!

Gründe !

Zwei oder mehr Prozesse warten auf „Betriebsmittel“, die nur der/die andere(n) Wartende(n) freigeben kann/können!

Kombination von Randbedingungen muss vorliegen !

Betriebsmittel werden exklusiv von einem Prozess belegt !

Jeder beteiligte Prozess hat bereits solche Belegungen und wartet auf weitere !

Belegte Betriebsmittel können nicht zwangsentzogen werden (geschachtelte kritische Abschnitte) !

After-You-After-You-Problem (Nebenläufigkeit):! Schlechte Implementierungen für gegenseitigen Ausschluss erzeugen dieses Problem: Beide Prozesse können durch raceConditions nicht arbeiten, weil sie immer dem anderen Prozess oder Thread den vortritt lassen wollen um gemeinsamen Zugriff auf einen kritischen Abschnitt zu vermeiden.!

15. Wie löst du das Producer-Consumer Problem mit Semaphore? (unbegrenzerter Puffer) 1

! Sem s(0); ! ! //locked ! ! //Producer ! erzeugen();! s.V();! ! ! //s++
!
Sem s(0); !
!
//locked !
!
//Producer !
erzeugen();!
s.V();!
!
!
//s++ !
!
//Consumer !
s.P();!
!
!
//s-- !

verbrauchen();!

16. Wenn der Buffer zum Erzeugen eine Größe von 3 hat, wie löst du das mit Semaphoren?

Sem s1(0); ! Sem s2(3); !

 

//locked !

//unlocked !

//Producer !

s2.P() !!

// - auf 2, bleibt unlocked !

erzeugen();!

s1.V() !!

// ++ auf 1, wird unlocked !

!

//Consumer !

s1.P(); !!

// - auf 0, wird locked !

verbrauchen();!

s2.V();!!

// + auf 3, bleibt unlocked !

17. Was ist synchrone und asynchrone Kommunikation? Was passiert bei der asynchronen mit den gesendeten Daten?

!

Einordnung !

Unterschieden von: Synchronisation / Kommunikation von (Prozessen/) Threads über gemeinsame Variablen oder Objekte (Schlossvariablen, Semaphore, Monitoren), da dies einen gemeinsamen Adressraum voraussetzt, der nicht immer gegeben ist. !

Gegenbeispiele: UNIX-Prozesse (statt Threads) ohne Shared Memory, Verteilte System / Rechnernetze !

Benutzung in der Interprozesskommunikation !

durch send(Prozess2, Nachricht) und receive(Prozess1, Puffer) ist gegenseitiger Ausschluss implizit, einseitige Synchronisation implizit. !

Nachrichtenaustausch kann auch auf gemeinsamen Variablen simuliert werden !

Kommunikationskanal = gemeinsamer Speicherbereich !

Senden einer Nachricht = Schreiben einer Variable !

Empfangen einer Nachricht = Lesen einer Variable !

Wenn man das so macht, ist Schutz des gemeinsamen Speicherbereichs erforderlich: Locks, Monitore, etc. !

!

Bedeutung in Rechnernetzen !

Synchrone Kommunikation!

send()/recive() sind blockierend !

Sender / Empfänger warten aufeinander !

Setzt wissen über Empfangsbereitschaft voraus; in verteilten Systemen nicht ohne weiteres bekannt !

Verklemmungsgefährdet wenn nicht aufeinander abgestimmt !

Asynchrone Kommunikation!

send() nicht blockierend !

receive() i.d.R. schon !

Senden vor Empfangsbereitschaft möglich. Erfordert Puffern im Kommunikationskanal !

Gefahr: Pufferüberlauf; Alternative: send() wirft bei Überlauf Fehler; receive() bei leeren Puffer !

Synchrone Kommunikation durch asynchrone Operationen!

Obwohl technisch anders möglich, warten auf Empfangsbestätigung einbauen !

Asynchrone Kommunikation durch synchrone Operationen!

Pufferprozess einführen !

Modellierung mit Semaphoren !

Asynchrone Kommunikation

Sema s1(0);

 

Prozess1

Prozess2

send(Nachricht);

s1.P():

s1.V():

receive(Nachricht);

Synchrone Kommunikation (annähernd) ! Sema s1(0); Sema s2(0);

Prozess1

Prozess2

 

 

send(Nachricht);

s1.P();

s1.V():

receive(Nachricht);

s2.P();

s2.V();

17. Was wird in Unix-Systemen benutzt? Wohin gehören Sockets?

(Unnamed) Pipes: Unidirektional (müssen den selben Vaterprozess haben) !

Named Pipes: Bidirektional !

Sockets: Biderektional, nicht nur sequentielle Byteströme, auch über Systemgrenzen hinweg, unterstützt unterschiedliche Kommunikationsformen: !

Bidirektionale Pipe (TCP) "Telefongespräch" !

Bytestrom !

sequentielle Übertragung !

zuverlässig!

verbindungsorientiert !

!

Datagram-Socket (UDP) "Brief-/Paketzustellung" !

Nachrichten (Pakete) !

beliebige Reihenfolge !

u.U. unzuverlässig (Verluste, Duplikate) !

verbindungslos !

!

!