B e t r i e b s s y s t e m e
Vorlesung im Wintersemester 2003/04
Dozent: Prof. Dr. A. Söder
Zeiten: 4 Std. Vorlesung, 2 Std. Übungen
Vorlesung:
Alle: Montag 1.Std 08.15-09.45 Uhr Raum: 213
Alle: Freitag 1.Std 08.15-09.45 Uhr Raum: 213
Übungen:
G1: Montag 2.Std 10.00-11.30 Uhr Raum: 514
G2: Montag 3.Std 11.45-13.15 Uhr Raum: 514
G3: Dienstag 5.Std 15.15-16.45 Uhr Raum: 514
G4: Mittwoch 4.Std 13.30-15.00 Uhr Raum: 514
Leistungsnachweis: schriftliche Prüfung
Zeit: 120 Min (am Semesterende)
Voraussetzung: erfolgreiche Teilnahme an den Übungen Zugel. Hilfsmittel: Skript, Übungsaufgaben inkl. Lösungen
Ziele der Vorlesung:
- Kennenlernen der wesentlichen Aufgaben, Dienste und Komponenten eines Betriebssystems.
- Kennenlernen von ausgewählten Problemen der Betriebssystementwicklung und der einschlägigen Lösungsansätze (Strategien, Konzepte und Algorithmen) - Beurteilen von vorgegebenen Lösungansätzen sowie Entwurf von eigenen
Lösungskonzepten.
- Praktische Anwendung der Lehrinhalte auf konkrete Problemsituationen durch eine Reihe von Übungen auf UNIX mit Schwerpunkt Prozessverwaltung (Interprozesskommunikation, Synchronisation, Paralellverarbeitung) in Teamarbeit
Vorlesung Betriebssysteme - Gliederung der Vorlesung
1 Einführung
Rechnerhardware, Programme und Ablauf Historische Entwicklung
2 Übersicht
Betriebssystemsichten und Schnittstellen Aufgaben, Dienste, Komponenten
3 Prozess- und Prozessorverwaltung Prozessbegriff
Prozessverwaltung Prozessorzuteilung
Interprozesskommunikation
Interaktionsmuster und Synchronisation Prozesssysteme
4 Betriebsmittelverwaltung Betriebsmittelbelegung Verklemmungen
Zugriffschutz Konfigurierung
5 Zentralspeicherverwaltungsverfahren Speicherverwaltungsverfahren Adressiermechanismen
Virtueller Speicher
Seitenaustauschstrategien
"Thrashing-Effekt"
6 Ein/Ausgabesteuerung
Ein/Ausgabekonfiguration
Logische und Physikalische Ein/Ausgabe
Empfohlene Literatur:
Wettstein, H., Architektur von Betriebssystemen München-Wien: Hanser Verlag 1988 Werner, D., Theorie der Betriebssysteme
München-Wien: Hanser Verlag 1992 Tanenbaum,A.S., Moderne Betriebssysteme
München-Wien: Hanser Verlag 1996
Silberschatz, A., Galvin, P., Operating System Concepts Addison Wesley Publishing Company, Reading 1999 Bach, M.J., The Design of the UNIX Operating System
Prentice Hall, Englewood Cliffs 1986
Vorlesung Betriebssysteme 03/04 - Übersicht über Übungen
Aktionen:
a) Bilden von 2 Hauptgruppen: G1/ G2 bzw. G3/G4 (jeweils ca. halbe Studiengruppe) b) Bilden von Gruppen (2-3 Teilnehmer) innerhalb der Hauptgruppen
Regeln:
(1) Jede Übung muss termingerecht abgegeben werden.
(Abgabetermine werden in Vorlesung bekanntgegeben!) (2) Jede abgegebene Übung enthält:
- Namen der Gruppenmitglieder - Kurzdokumentation der Lösung
- SourceCode der Lösung bzw. Antwort auf Fragen
- Nachweis der Korrektheit bei Programmen in Form von Testprotokollen (3) Jede Gruppe präsentiert mindestens eine Übungsaufgabe beim Dozenten (4) Jede Gruppe lässt sich die erfolgreiche Abgabe von Übungen
sowie die Präsentation vom Dozenten auf einem Formblatt bestätigen
Inhalte:
Übung 1: Einstieg in fork(), exec (), pipes Übung 2: Interprozesskommunikation mit pipes Übung 3: Experimente mit pipes
Es gibt 4 Alternativen. Pro Gruppenmitglied ist je eine unterschiedliche Alternative zu realisieren
Übung 4: Shared Memory und Semaphore
Hilfsmittel:
UNIX Manuale
Skript Blockpraktikum
Formblatt:
Teilnehmer:
--- Übung Nr. 1 Nr. 2 Nr. 3 Nr. 4 Präsentation --- Datum:
--- Unterschrift:
Übungen zur Vorlesung BT WS03/04 Seite 1
Übung 1: Einstieg in fork(), exec..(), pipes
1.1 Was geben die folgenden Programme aus? Testen Sie, wie die Ausgaben von einer Pufferung abhängen. Puffer können mit setbuf(Datei,Puffer) gesetzt werden. Hat eine Umlenkung "Programm > xx" Einfluß auf die Ausgabe?
Programm 1:
#include <stdio.h>
main() {
int i;
for (i = 0; i<= 2; i++) {
fork ();
printf ("PID=%6d, i=%d\n", getpid(), i);
} }
Programm 2:
#include <stdio.h>
void exectest(void) {
printf ("The quick brown fox jumped over");
execl ("/bin/echo", "echo", "the", "lazy", "dogs.", NULL);
}
main() {
exectest();
}
Übungen zur Vorlesung BT WS03/04 Seite 2
1.2 Analysieren Sie die durch das folgende Programm gegebenen Prozessabläufe. Geben Sie alle beteiligten Prozesse sowie den Zustand aller Dateideskriptoren der Prozesse an!
Welche Funktion wird durch das Programm erreicht?
#define READ 0
#define WRITE 1
void Fehler (char *Text)
{ fprintf (stderr, "Fehler : %s in %d\n, Text, getpid());
exit (1);
}
int Pipe[2];
int Kommando (char *Cmd, char *Par, int Modus) { char Zeile[80];
switch (fork()) {
case -1 : Fehler ("Fork()");
case 0 : close (Modus);
dup (Pipe[Modus]);
close (Pipe[0]);
close (Pipe[1]);
strcpy (Zeile, "/bin/");
strcat (Zeile, cmd);
execl (Zeile, cmd, Par, NULL);
default : printf ("Fork erfolgreich\n");
} }
main() {
pipe (Pipe);
Kommando ("cat", Name einer Text-Datei, WRITE);
Kommando ("sort", NULL, READ);
}
Übungen zur Vorlesung BT WS03/04 Seite 3
Übung 2: Interprozess-Kommunikation in UNIX
Die Übung stellt den sogenannten "pipe"-Mechanismus in UNIX vor. An Hand eines Beispiel- Programms, in dem Sie nur noch einige Funktionen zu ergänzen brauchen, sollen Sie sich den Mechanismus klarmachen.
Beispiel: Kommunikation dreier paralleler Prozesse
Es ist Prüfungstag am Institut. Das Sekretariat hat in einem Ordner die Zulassungszettel aller Prüfungskandidaten gesammelt und gibt sie nun an den Prüfer weiter. Der Prüfer trägt in jeden Zettel die erreichte Note ein und schickt ihn an das Prüfungsamt.
Sekretariat, Prüfer und Prüfungsamt sind nun als parallele Prozesse realisiert, die über pipes Zulassungszettel austauschen.
Der Zulassungszettel soll in C eine Struktur sein:
typedef struct {
char Name420];
char Vorname[20];
long Matrikel_Nr;
int Note;
} ZETTEL, *ZULASSUNG;
Die Prozesse werden wie folgt erzeugt:
/************************************************************/
/* */
/* Erzeugen dreier paralleler Prozesse, die über pipes */
/* kommunizieren: */
/* */
/* SEKRETARIAT ---> PRÜFER --->PRÜFUNGSAMT */
/* PIPE_1 PIPE_2 */
/* */
/************************************************************/
Übungen zur Vorlesung BT WS03/04 Seite 4
void Sekretariat(int), Pruefer(int,int), Pruefungsamt(int);
main() {
int Pipe_1[2], Pipe_2[2]; /* pipe-Deskriptoren */
int Status_1, Status_2;
Status_1 = pipe(PIPE_1); /* Erzeugen der pipes */
Status_2 = pipe(PIPE_2);
if ((Status_ 1 == -1) || (Status_2 == -1)) /* pipe() liefert */
printf("\n!!! kann pipe nicht erzeugen\n"); /* im Fehlerfall-1*/
else
if (fork() == 0) /* nicht Vater */
{
if (fork() == 0) /* Enkel */
{
close (Pipe_1[0]); /* darf in Pipe_1 nicht lesen */
close (Pipe_2[0]); /* darf in Pipe_2 nicht lesen */
close (Pipe_2[1]); /* darf in Pipe_2 nicht schreiben */
Sekretariat(Pipe_1[1]);
}
else /* erstes Kind */
{
close(Pipe_1[1]); /* darf in Pipe_1 nicht schreiben */
close(Pipe_2[0]); /* darf in Pipe_2 nicht lesen */
Pruefer(Pipe_1[0], Pipe_2[1]);
} } else {
if (fork() == 0) /* zweites Kind */
{
close(Pipe_1[0]); /* darf in Pipe_1 nicht lesen */
close(Pipe_1[1]); /* darf in Pipe_1 nicht schreiben */
close(Pipe_2[1]); /* darf in Pipe_2 nicht schreiben */
Pruefungsamt(Pipe_2[0]):
}
/* der Vaterprozess stirbt nach Erzeugen der Kind- */
/* prozesse, dabei wird implizit für jeden */
/* seiner pipe-Deskriptoren 'close' aufgerufen. */
}}
Übungen zur Vorlesung BT WS03/04 Seite 5
Aufgabe :
a) Erstellen Sie die obige Datenstruktur für den Zulassungszettel und den obigen Programmrahmen.
b) Schreiben Sie die Funktionen Sekretariat, Prüfer und Prüfungsamt:
Sekretariat(int Pipe_PRUE) {
/* liest mittels "scanf()" die Zulassungszettel */
/* (Name, Vorname, Matrikelnummer) ein und schreibt */
/* sie in die Pipe mit Deskriptor Pipe_PRUE. */
}
Pruefer(int Pipe_SEKR, int Pipe_AMT) {
/* liest Zulassungszettel aus der pipe Pipe_PRUE,*/
/* trägt eine Note ein und schreibt die Zettel */
/* in die pipe Pipe_AMT. */
}
Pruefungsamt(int Pipe_PRUE)
{ /* liest Zulassungszettel aus der pipe Pipe_PRUE */
/* und gibt sie mittels "printf()" aus */
}
c) Schreiben Sie Datensätze in dem von "scanf()" in Sekretariat verlangten Format in eine Datei "Ordner".
d) Starten Sie das Programm: prog <Ordner >Ausgabe
In der Datei "Ausgabe" sollten nach dem Programmlauf alle Zulassungszettel aus "Ordner"
mit Noten stehen.
In der Datei "Ausgabe" sollten nach dem Programmlauf alle Zulassungszettel aus "Ordner"
mit Noten stehen.
Hinweise:
Überzeugen Sie sich nach dem Programmlauf mit dem Kommando 'ps' davon , daß alle drei Prozesse beendet wurden!!
Notfalls können Prozesse mit 'kill <pid>' gewaltsam beendet werden.
Übungen zur Vorlesung BT WS03/04 Seite 6
Übung 3: Experimente mit pipes
--- Alternative 1: Sekretär
---
Der Sekretär soll die Dienstleistungen "Addieren zweier Zahlen" und "Multiplizieren zweier Zahlen" anbieten.
Zur Realisierung der Interaktion brauchen Sie eine pipe, über die der Sekretär seine Aufträge erhält und je eine pipe als Rückkanal zu jedem auftraggebenden Prozess.
1. Schritt: nur ein Auftraggeber ( 1:1 - Beziehung )
Ein Prozess soll das Skalarprodukt zweier Vektoren bilden. Die dabei anfallenden Additions- und Multiplikationsoperationen vergibt er als Aufträge an den Sekretär. Den nächsten Auftrag erteilt er immer erst dann, wenn das Ergebnis des
vorhergehenden Auftrags eingetroffen ist, die Puffereigenschaft der pipe wird also nicht ausgenutzt.
Überlegen Sie sich ein Format für Aufträge und die Rückmeldung von Ergebnissen.
2. Schritt: mehrere Auftraggeber ( m:1 - Beziehung )
Erzeugen Sie mindestens zwei auftraggebende Prozesse. Jeder Auftrag muss jetzt auch eine Information über den Rückkanal enthalten!
3. Schritt: mehrere Auftraggeber und Sekretäre ( m:n - Beziehung)
Zur Effizienzsteigerung soll es nun auch mehrere Exemplare des Sekretärs (mindestens 2) geben.
Machen Sie die beiden Dienstleistungen des Sekretärs durch Aufrufe von
"sleep(<Zeit in Sekunden>)" oder Zählschleifen (Vorsicht vor Optimierungen im Compiler) unterschiedlich schnell und sorgen Sie dafür, daß die
Auftraggeber jeweils unterschiedliche Folgen von Additions- und Multiplikationsaufträgen erzeugen.
Halten Sie fest , welcher Sekretär welchen Auftrag bearbeitet hat!
Hinweis:
Sorgen Sie dafür, daß die Arbeit möglichst gleichmäßig auf alle Sekretäre verteilt wird, und daß das Prozesssystem sich selbständig definiert beendet.
Übungen zur Vorlesung BT WS03/04 Seite 7
--- Alternative 2: Pufferung p-fach zur Realisierung von Parallelität ---
Ein Prozess stellt die Dienstleistung "Addieren zweier Zahlen" zur Verfügung.
Zur Realisierung der Interaktion brauchen Sie eine pipe, über die der Prozess seine Aufträge erhält und eine pipe als Rückkanal zum Auftraggeber.
1. Schritt: 1:1 - Beziehung
Ein Prozess soll zwei Vektoren addieren. Die Addition einer Komponente vergibt er jeweils als Auftrag. Überlegen Sie sich ein Format für Aufträge und die Rückmeldung von Ergebnissen.
Die Puffereigenschaft der pipe erlaubt es vor der ersten Empfangsoperation (Lesen aus dem Rückkanal) Aufträge "auf Vorrat" in den Hinkanal zu schreiben.
Vermeiden Sie bei der Implementierung einen Deadlock!
Wievielfach darf die Pufferung sein ? 2. Schritt: 1:n - Beziehung
Erzeugen Sie nun mehrere Exemplare (mindestens drei) des Dienstleistungsprozesses.
Stellen Sie fest, ob die Ergebnisse in der gleichen Reihenfolge eintreffen, wie die Aufträge erteilt wurden!
3. Schritt:
Machen Sie die Dienstleistungsprozesse durch Aufrufe von
"sleep(<Zeit in Sekunden>)" oder Zählschleifen unterschiedlich schnell.
Es kommt nun auf jeden Fall zu Überholungen der Aufträge. Halten Sie fest, welcher Prozess welchen Auftrag bearbeitet hat und in welcher Reihenfolge die Ergebnisse eintreffen.
Hinweis:
Sorgen Sie dafür, daß die Arbeit möglichst gleichmäßig auf alle Sekretäre verteilt wird, und daß das Prozeßsystem sich selbständig definiert beendet.
Übungen zur Vorlesung BT WS03/04 Seite 8
--- Alternative 3: Alternierung (Erzeuger-Verbraucher-Problem) ---
Es ist ein Prozess-System zu realisieren, in dem eine feste Anzahl von "Behältern" zirkuliert.
1. Schritt: zwei Prozesse, ein Behälter (einfaches Erzeuger-Verbraucher-Problem) Der Erzeuger legt eine Zufallszahl (siehe rand(3) ) in dem Behälter ab
und sendet ihn über eine pipe an den Verbraucher. Der zählt die Zufallszahl auf 0 herunter und sendet den Behälter über eine zweite pipe zurück an den Erzeuger, der wieder eine Zufallszahl erzeugt usw.
Überlegen Sie sich ein Format für den Behälter.
Zur Initialisierung muss der Erzeuger zunächst den leeren Behälter an sich selbst senden!
2. Schritt: vier Prozesse, ein Behälter (Rotationsbeziehung)
Verdoppeln Sie einfach das Prozess-System aus dem ersten Schritt.
Der erste Verbraucher sendet den Behälter an einen zweiten Erzeuger, der wieder eine Zufallszahl einfüllt, die der zweite Verbraucher herunterzählt.
Der zweite Verbraucher sendet den Behälter dann wieder an den ersten Erzeuger.
3. Schritt: vier Prozesse, mehrere Behälter (Rotationsbeziehung mit Mehrfachinitialisierung) Führen Sie schrittweise mehr Behälter ein.
Wieviele Behälter sind maximal möglich ?
Durch die Verwendung der Zufallszahlen sind die Laufzeiten der Behälter durch das Prozess-System unterschiedlich.
Versuchen Sie herauszubekommen, wo sich Behälter stauen.
Hinweis:
Sorgen Sie dafür, daß die Arbeit möglichst gleichmäßig auf alle Sekretäre verteilt wird, und daß das Prozeßsystem sich selbständig definiert beendet.
Übungen zur Vorlesung BT WS03/04 Seite 9
--- Alternative 4: Team
---
Das Team soll aus zwei Prozessen bestehen, die entweder die Funktion "Addieren zweier Zahlen" oder "Multiplizieren zweier Zahlen" anbieten.
Zur Realisierung der Interaktion brauchen Sie je eine pipe, über die die einzelnen
Teamprozesse ihre Aufträge erhalten und je einen Rückkanal von den Teamprozessen zu den auftraggebenden Prozessen (d.h. für jeden Teamprozess zwei pipes).
1. Schritt: nur ein Auftraggeber ( 1:2 - Beziehung )
Ein Prozess soll das Skalarprodukt zweier Vektoren bilden. Die dabei anfallenden Additions- und Multiplikationsoperationen vergibt er als Aufträge an die
entsprechenden Teamprozesse. Den nächsten Auftrag erteilt er immer erst dann, wenn das Ergebniss des vorhergehenden Auftrags eingetroffen ist.
Überlegen Sie sich ein Format für Aufträge und die Rückmeldung von Ergebnissen.
2. Schritt: mehrere Aufträggeber ( m:2 - Beziehung )
Erzeugen Sie mindestens zwei auftraggebende Prozesse. Jeder Auftrag muss jetzt auch eine Information über den Rückkanal enthalten!
3. Schritt: mehrere Auftraggeberund Teamprozesse (m:n - Beziehung)
Zur Effizienzsteigerung soll nun das Team vergrößert werden. Es sollte mindestens einer der Teamprozesse mehrfach vorhanden sein.
Überlegen Sie sich, welcher Teamprozess (Addierer oder Multiplizierer) sinnvoller Weise vervielfältigt werden sollte !
Machen Sie die beiden Dienstleistungen des Teams durch Aufrufe von "sleep(<Zeit in Sekunden>)" oder Zählschleifen unterschiedlich schnell und sorgen Sie dafür, daß die Auftraggeber jeweils unterschiedliche Folgen von Additions- und Multiplikations- aufträgen erzeugen. Halten Sie fest, welcher Teamprozess welchen Auftrag bearbeitet hat!
Hinweis:
Sorgen Sie dafür, daß die Arbeit möglichst gleichmäßig auf alle Sekretäre verteilt wird, und daß das Prozeßsystem sich selbständig definiert beendet.
--- Allgemeine Hinweise (gelten für jede der Alternativen):
---
-- Dokumentieren Sie in jedem Versuchsschritt die Ergebnisse.
Dazu müssen Sie während des Ablaufs Ihres Prozess-Systems Daten sammeln und in sinnvoller Forn ausgeben.
Sie können z.B. Nachrichten (Aufträge, Behälter) von jedem Prozess mit einem Zeitstempel und der eigenen Prozessnummer versehen lassen.
-- Starten Sie Ihr Prozess-System grundsätzlich als Hintergrund prozess ('&' angeben)!!
Sie können dann notfalls Prozesse mit "kill(<PID>) vom eigenen Terminal aus beenden.
-- Prüfen Sie immer mit "ps" nach, ob alle erzeugten Prozesse beendet wurden !!
Übungen zur Vorlesung BT WS03/04 Seite 10
Übung 4: Shared Memory und Semaphore
1.) Modifizieren Sie die Programme aus Übung 3 auf folgende Weise:
a) Der Austausch von Daten zwischen den Prozessen findet über je einen gemeinsamen Buffer im Shared Memory statt.
b) Die Prozesse synchronisieren sich über Semaphore. Falls der Semaphormechanismus von UNIX nicht ausreichen sollte, sind zusätzlich eigene Synchronisationsfunktionen zu erstellen
Hinweis: Nutzen Sie hierbei aus, daß über diesen Mechanismus auch "nicht verwandte" Prozesse miteinander kommunizieren können.
Erzeugen Sie deshalb die benötigten Prozesse nicht per "fork", sondern per Programmaufruf von unterschiedlichen Terminals.