Weitere Hinweise zu den Übungen Betriebssysteme

Betriebssysteme
Übungsaufgabe 1
Prozesse verwalten
Weitere Hinweise zu den Übungen Betriebssysteme
• Ab jetzt ist es nicht mehr möglich, Einzelabgaben in AsSESS zu tätigen. Falls ihr (statt in
einer Dreiergruppe) zu zweit oder zu viert abgeben möchtet, klärt das bitte vorher mit Eurem
Übungsleiter!
• Die abgegebenen Antworten/Programme werden automatisch auf Ähnlichkeit mit anderen Abgaben überprüft. Wer beim Abschreiben1 erwischt wird, verliert ohne weitere Vorwarnung die
Möglichkeit zum Erwerb der Studienleistung in diesem Semester!
• Die optionalen Aufgaben (davon wird es jeweils eine auf den Aufgabenblättern 0–3 geben) sind
ein Stück schwerer als die „normalen“ und geben keine zusätzlichen Punkte für das jeweilige
Aufgabenblatt – aber jeweils ein „Bonus-Sternchen“ F. Wenn ihr drei Sternchen sammelt, müsst
ihr das letzte Aufgabenblatt (A4) nicht bearbeiten!
• In diesem Aufgabenblatt ist das Bonus-Sternchen auf eine Theorie- und eine Programmieraufgabe aufgeteilt. Zum Erlangen des Sternchens ist es notwendig beide Aufgaben erfolgreich zu
bearbeiten. Die „Anregungen“ in der entsprechenden Programmieraufgabe gehen nicht in die
Bewertung ein und sind lediglich als Anregung zum „Spielen“ zu verstehen! Lösungen dafür sind
nicht mit abzugeben und werden nicht korrigiert.
• Am Besten arbeitet Ihr in diesem Blatt zuerst die Theoriefragen durch; die Programmieraufgaben
bauen z.T. stark auf dem Theorieteil auf.
• Führt den C-Code-Schnipsel und das Bash-Script (aus der Theorie-Aufgabe 4) nicht aus! Eine
theoretische Betrachtung ist zum Lösen der Aufgabe mehr als ausreichend!
Aufgabe 1: Prozessverwaltung und fork() (10 Punkte)
Lernziel dieser Aufgabe ist die Verwendung der UNIX-Systemschnittstelle zum Erzeugen und Verwalten
von Prozessen.
Theoriefragen: Prozessverwaltung (5 Punkte)
Bitte gebt diesen Aufgabenteil, wie auch in Aufgabe 0, in der Datei antworten.txt ab. Die Antworten
sind in eigenen Worten zu formulieren.
1) Erklärt den Unterschied zwischen fork(2) und vfork(2)? Gibt es zwischen den beiden heutzutage
effektiv noch einen Unterschied?
2) Wozu dienen die Operatoren „>‌>“ und „<“ der Unix-Shell?
3) Was muss getan werden, damit ein Kindprozess nicht zum Zombieprozess wird?
4) Betrachtet folgenden C-Code-Schnipsel: /!\ nicht ausführen /!\
for(;;) fork();
a) Beschreibt das Programmverhalten nach 1, 2, 3 und n „Generationen“. Legt zu Grunde, dass
alle Prozesse (hier insbesondere obige for-Schleife) parallel ausgeführt werden. Betrachtet die
Gesamtheit der parallelen Schleifendurchläufe als „Generation“.
b) Das Verhalten eines solchen Programms kann zu Problemen führen und mittels /etc/security/limits.conf
beschränkt werden. Welche Probleme sind dies und warum sind Gegenmaßnahmen sinnvoll?
Gebt ferner beispielhaft Einträge für diese Datei an, die den Benutzer „tux“ hart auf 100 und
die Gruppe „guests“ hart auf 2000 Prozesse limitieren (man 5 limits.conf ).
1
Da wir im Regelfall nicht unterscheiden können, wer von wem abgeschrieben hat, gilt das für Original und Plagiat.
c 2015 TU Dortmund, Informatik 12, Arbeitsgruppe Eingebettete Systemsoftware
Betriebssysteme
Übungsaufgabe 1
Prozesse verwalten
c) Äquivalentes in anderer Sprache optional (F/2) /!\ nicht ausführen /!\
Das Bash-Skript :() { :|:& }; : ist ähnlich zu obigem C-Code. Warum? Beschreibt das Skript und
dessen Verhalten in eigenen Worten.
Tipps:
• Sucht in bash(1) nach control operator &.
• „:“ ist der Name einer Funktion, die im Skript definiert und aufgerufen wird.
Programmierung: Menü / Shell (5 Punkte)
In dieser Aufgabe soll ein einfaches Menü implementiert werden. Hierbei sollt Ihr für jede Teilaufgabe
eine eigene Datei anlegen und die vorherige erweitern. Legt dazu die Datei aufgabe1_a.c an und
erstellt darin Euer Programm für Teilaufgabe a). Sobald Ihr diese Aufgabe gelöst habt, kopiert Ihr
aufgabe1_a.c in die Datei aufgabe1_b.c und erweitert den Code um die Vorgaben/Anforderungen
aus Teilaufgabe b). Bei den restlichen Teilaufgaben geht Ihr analog vor.
a) Einlesen aus der Standardeingabe Implementiert zunächst ein einfaches Menü, welches mittels printf(3) ausgegeben wird. Das Menü soll den Benutzer auffordern einen von vier möglichen
Menüeinträgen auszuwählen. Anschließend soll das entsprechende Kommando mittels printf(3) ausgegeben werden. Die möglichen Programmeinträge sollen „geany“, „ps“ , „xterm“ und „top“ sein.2 .
Die Eingabemöglichkeit für den Benutzer sollen die Tasten „g“, „p“, „x“ und „o“ sein. Nach einer
Eingabe soll das ausgewählte Kommando ausgegeben werden und erneut die Möglichkeit zur Eingabe
eines Kommandos bestehen. Das Einlesen von Tasten ist mit der Funktion scanf(3) möglich. Das
Eingabe-Formatzeichen „%c“ ermöglicht das Lesen eines Zeichens in eine char-Variable. Drückt der
Benutzer die Tastenkombination <Ctrl+c>, so soll das Programm beendet werden.
Erstellt für die Fehlerbehandlung eine Fehlerfunktion void error(char *str), die als minimalistische Fehlerbehandlung perror(3) und exit(3) aufruft. Benutzt diese Fehlerfunktion bei allen
eingesetzten Systemaufrufen zur Fehlerbehandlung in allen Teilaufgaben.
b) Starten von Programmen Nun sollen nicht mehr nur die Programmnamen ausgegeben werden, sondern die jeweiligen Programme gestartet werden. Beachtet dabei das Puffer-Verhalten der
Funktion printf(3). Es muss ein neuer Prozess mittels fork(2) erzeugt werden, der die Ausführung
des Programmes mithilfe von execlp(3) startet. Der Typ „pid_t“ ist in „<sys/types.h>“ definiert. Der
Vaterprozess soll nach dem Aufruf von fork(2) die Prozess-ID des Kindprozesses ausgeben und dann
erneut auf Benutzereingaben warten, während parallel der Kindprozess ausgeführt wird. Implementiert
eine kurze Wartezeit von 2s nach der Ausführung des fork(2) Befehls, damit sich die Ausgaben nicht
überlappen.
c) Wegräumen von Prozessen Sobald Teilaufgabe b) funktioniert, beobachtet die mit eurer UserID gestarteten Prozesse (ps(1) oder top(1)). Die gestarteten Programme, die bereits terminiert sind,
werden hier noch gelistet. Sie verbleiben im System, solange sie nicht mit wait(2) bzw. waitpid(2)
weggeräumt werden. Implementiert das Wegräumen eurer gestarteten Prozesse nachdem ihr fork(2)
im Vaterprozess aufgerufen habt.
2
Sofern Ihr einen eigenen Linux-Rechner nutzt und die Programme nicht vorhanden sind, könnt ihr auch andere
Kommandos verwenden
c 2015 TU Dortmund, Informatik 12, Arbeitsgruppe Eingebettete Systemsoftware
Betriebssysteme
Übungsaufgabe 1
Prozesse verwalten
d) Ausführen beliebiger Befehle optional (F/2) Fügt zu euren bestehenden Menüeinträgen
einen weiteren Eintrag hinzu, welcher die Möglichkeit bietet beliebige Befehle auszuführen. Dazu
müsst ihr, nachdem der Menüeintrag ausgewählt wurde, mithilfe von scanf(3) einen String einlesen,
was durch das Formatzeichen „%s“ möglich ist. Beachtet dabei die Größe eures Buffers und die Länge
der Eingabe. Überprüft nach dem Aufruf von execlp(3), ob die Ausführung erfolgreich war.
Tipps zu den Programmieraufgaben:
• Kommentiert Euren Quellcode ausführlich, so dass wir auch bei Programmierfehlern im Zweifelsfall noch Punkte vergeben können!
• Denkt daran, dass viele Systemaufrufe fehlschlagen können! Fangt diese Fehlerfälle ab (die
Aufrufe melden dies über bestimmte Rückgabewerte, siehe die jeweiligen man-Pages), gebt
geeignete Fehlermeldungen aus (z.B. unter Zuhilfenahme von perror(3)), und beendet euer
Programm danach ordnungsgemäß.
• Die Programme sollen sich mit dem gcc auf den Linux-Rechnern im FBI-Pool übersetzen lassen.
Der Compiler ist dazu mit folgenden Parametern aufzurufen: gcc -Wall -o ziel datei1.c
Weitere (nicht zwingend zu verwendende) Compilerflags, die dafür sorgen, dass man sich enger
an die Standards hält, sind: -ansi -pedantic -Werror
• Alternativ kann auch der GNU C++-Compiler (g++) verwendet werden.
Abgabe: bis spätestens Donnerstag, 07. Mai 10:00 (Übungsgruppen 1/3/5/. . . ) bzw. Dienstag, 12. Mai 10:00 (Übungsgruppen 2/4/6/. . . ).
c 2015 TU Dortmund, Informatik 12, Arbeitsgruppe Eingebettete Systemsoftware