Prozesse und Threads
von: D.F.
von: D.F.
-
- 1 / 34
-
Flashcards
Wie ist der Begriff Prozess definiert?
Prozess: ein Programm, das gerade in einem Rechner ausgeführt wird und alle zur Ausführung notwendigen Daten.
Es sollen mehrere Prozess gleichzeitig auf eienm Rechner laufen, dabei steht nur eine CPu zur verfügung. Wie lässt sich dies realisieren?
Das ganze läuft unter den Begriffen Multi-Tasking oder Multi-Processing. Eine mögliche Lösung ist es die Programme in rascher Folge abzuwechseln, um so die Illusion paraleller Ausführung zu erwecken.
Was muss beim Wechsel zwsichen zwei Prozessen berücksichtigt werden?
- Informationenen über den aktuellen Systemzustand müssen gespeichert werden (Register, usw...)
- Es muss ein effizientes und "gerechtes" Verfahren gefunden werden, nach dem die Reihenfolge der
auszuführenden Prozesse bestimmt wird (Scheduling)
Was ist das Kooperative Multitasking?
Kooperatives Multitasking: Die Prozesse stimmen sich untereinander ab.
Nachteil: Ist ein prozess eingensinning und geht nie in den sleep Betreibszustand, dann wird die komplette CPU durch diesen Prozess blockiert.
Was ist die alternative zum Kooperatives Multitasking?
Präemptives Multitasking: Das Betriebssystem entscheidet, welcher Prozess wann und wie lange läuft
Vorteil: Einzelner prozess kann die CPU nicht blockieren.
Nachteil: Zeitkritische Prozesse könnten unterbrochen werden, was dazu führen kann dass ihre Operationen nicht mehr rechtzeitig Ausgeführt werden.
Nach welchem Schema lassen sich Prozesse identifizieren?
(3 Punkte)
Jeder Prozess hat eine:
- eindeutige Prozess-ID (PID)
- Parent-Process-ID (PPID) => PID des Elternprozesses (Ausnahme Urprozess init/systemd PID = 1)
- Process-Group-ID die durch die PID des ersten Prozesses in der Gruppe beschrieben wird
Welche Informationen enthält die Prozesstabelle für jeden Prozess (PCB)?
Alle Informationen sind elementar für den Kernel, deshalb wird für jeden Prozess wird vom Kernel ein Prozesstabelleneintrag
gepflegt !
- Scheduling-Parameter
- Priorität, kürzlich
- verbrauchte CPU-Zeit,
- kürzlich schlafend verbrachte Zeit
- Speicherinformationen
- Zeiger auf die aktuellen Positionen im Text-, Daten- und Stacksegment
- Signalinformationen
- Welche Signale werden ausgewertet, welche ignoriert?)
- Verschiedenes
- Prozesszustand, ggf.Ereignis, auf das gewartet wird
- PID, PPID, Benutzer- und Gruppeninformationen
Welche Informationen enthält der u-Bereich (User-Structure) ?
(10 Punkte)
Der u-Bereich (User-Structure) enthält Informationen, die nicht gebraucht werden, so lange der Prozess nicht aktiv ist:
- Zeiger auf den zugehörigen Eintrag in der Prozesstabelle
- Reale und effiektive UID/GID
- Zugriffsmaske
- Login-Terminal
- Informationen zum aktuellen Systemaufruf (Parameter, Rückgabewert, Fehlermeldung)
- Dateideskriptoren der geöffneten Dateien
- Limitfelder (maximal benzutzbarer Speicher, maximale Stackgröße, ...)
- Timerfelder für verbrauchte CPU-Zeit (User-/Kernelmode)
- CPU-Register (Zustand vor Kernel-Trap)
- Kernel-Stack
Bei welcher gelegenheit wird in Unix ein nuer Prozess erzeugt?
- Systemstart
- Systemaufrufe in laufenden Prozessen
- Benutzer fordert neuen Prozess an
- Start eines Batch-Jobs
Wie lässt sich unter Unix ein Prozess clonen?
Mit dem Befehl fork() kann unter Unix ein Prozess geclont (Dupliziert) werden.
Rückgabewert ist im
- Elternprozess die PID des Kindprozesses
- Kindprozess 0
Das Textsegment wird von Eltern- und Kindprozess geteilt (Kind darf nur lesen), bis das
Kind versucht, zu schreiben. Dann wird eine Kopie erstellt ("copy on write")
Wie lässt sich unter Unix aus einem Prozess ein anderes Programm starten?
- Zuerst muss sich mit fork() das programm verzweigen
- Dann kann das Textsegment mittels des befehls exec*() augewechselt werden (Laden des eigentlichen neuen Programms)
Von dem exec*() befehl gibt es verschiedene varianten (Paramenter können teilweise kombiniert werden):
- e Es wird eine Environmentliste (Umgebungsvariablen) als Vektor erwartet.
- l Es werden die Kommandozeilenargumente in Form einer Liste erwartet.
- v Es werden die Kommandozeilenargumente in Form eines Vektors erwartet.
- p Es wird ein Dateiname und nicht ein Pfadname als Argument zum Aufruf des Programms erwartet.
Beispiel: int execl( const char *path, const char *arg1, ...) => Parameter l
Nach dem ausführen von exec*() blieben einige informationen erhalten, welche sind dies?
(10 Punkte)
- PID
- PPDI
- PGID
- Restzeit bis zum Weckalarm
- Aktuelles Arbeitsverzeichnis
- Zugriffsmaske
- Maximale Datei- und Speicherblockgrößen
- Dateideskriptoren offener Dateien
- Die bisherigen CPULaufzeiten des Programms
Was passiert wenn ein Elternprozess vor dem Kindprozess beendet wird?
Wird der Elternprozess vor dem Kindprozess beendet, geht die Elternrolle auf PID 1 (init/systemd) über.
Was passiert wenn ein Kindprozess beendet wird solange der Elternprozess noch läuft, aber nicht auf das Kind wartet?
Der Kindprozess wird zum "Zombie"
Reste des Prozesses (z.B. Rückgabewert) bleiben übrig, um später an den Elternprozess übergeben werden zu können.
Wie kann ein Prozess auf das Beenden irgendeines oder eines bestimmten Prozesses warten?
- pid_t wait( int *status )
- Wartet auf die Beendigung irgendeines Kindprozesses. Liefert die PID des beendeten Prozesses zurück
- Argument ist ein Zeiger auf den vom beendeten Prozess zurückgegebenen Status
- pid_t waitpid( pid_t pid, int *status,int options )
- wie wait, aber es wird auf einen ganz bestimmten Kindprozess gewartet
Aus welchen Gründen kann ein Unix-Prozess beendet werden?
- Ein Programm ist abgeschlossen
- Ein interner Fehler ist aufgetreten
- Systemfehler
- Beendet durch einen anderen Prozess
Wie kann sich ein Prozess freiwillig beenden?
- exit ( int status )
- Prozess wird beendet, der Rückgabewert (das LSB) wird an den Elternprozess zurückgegeben
- Alle noch offenen Dateien werden geschlossen
- Beim normalen Programmende ist status normalerweise 0
- Verschiedene Rückgabewerte können z.B. Fehlerursachen beschreiben
- _exit( int status )
- Wie exit(), aber es werden keien Dateipuffer mehr auf Platte geschrieben
Wie kann man ein Singal an einen anderen Prozess schicken und wie wird es von diesem abgefangen?
- kill( int pid, int signal )
- Schickt das Signal signal an den Prozess mit der PID pid
- signal( int signal, signalHandler )
- fängt Signale ab, die dem aktuellen Prozess zugesandt werden
- signal: Das Signal, auf das reagiert werden soll
- signalHandler: eine Funktion, die ausgeführt wird, wenn das Signal signal empfangen wird
Welche sind die wichtigesten Signale?
(5 Punkte)
- SIGHUP (1) => Hangup (Modem), häufig kann dadurch ein Programm neu initialisiert werden
- SIGINT (2) => Interrupt Taste wurde gedrückt
- SIGQUIT (3) => Quit-Taste wurde gedrückt
- SIGILL (4) => Illegaler Maschinencode
- SIGFPE (8) => Gleitkomma-Fehler (Überlauf,Nulldivision)
- SIGKILL (9) => Beenden "ohne Rücksicht auf Verluste"
- SIGBUS (10) => Bus-Error (meist falsche Zeiger in C-Programmen
- SIGSEGV (11) => Verbotener Speicherbereich adressiert
- SIGSYS (12) => Falsche Parameter in Systemaufruf
- SIGPIPE (13) => Schreiben in eine Pipe ohne lesenden Prozess
- SIGALRM (14) => Weckt einen Prozess, der mit pause() schlafen gelegt wurde
- SIGTERM (15) => Geregelt Beendigung eines Prozesses
Wie lässt sich ein verzögertes Signal an einen Prozess schicken?
- long alarm ( long time );
- Schickt nach time Sekunden ein SIGALRM (14) Signal an den aufrufenden Prozess
- Wenn der nicht abgefangen wird, beendet sich der Prozess
- Rückgabewert: die Zeit (in Sekunden) seit dem letzten Aufruf von alarm()
- Jeder Aufruf von alarm() setzt die Uhr neu
- alarm(0) annuliert den vorausgehenden Aufruf
Beispiele / Zusammenfassung
- Erzeugen von Programmen:
- Aus der Shell?
- Aus C-Programm?
- Beenden von Prozessen
- Von der Shell?
- Aus C-Programm
Beispiele / Zusammenfassung
- Erzeugen von Programmen:
- Aus der Shell: Kommando bzw. Kommando &
- Aus C-Programm: mit fork() und exec*()
- Beenden von Prozessen
- Von der Shell: kill –(9|15) <PID> (Signal 9 und 15)
- Aus C-Programm: kill() oder alarm()
Wie kann man anzeigen welche Prozesse gerade laufen (2 Varianten)?
Das ps-Kommando kennt zwei "Dialekte"
- System V oder Unix98
- Optionen beginnen mit '-'
- Beispiel: ps –ef (zeige alle Prozesse komplett an)
- BSD-Unix
- Optionen haben kein führendes '-'
- Beispiel: ps axl (zeige alle Prozesse komplett an)
- UID User-ID, unter der der Prozess abläuft
- PID Prozessnummer
- PPID Prozessnummer des Elternprozesses
- PRI Akutelle Priorität
- NI Nice Value
- VSZ Size of virtual Mamory (kB)
- RSS Resident Set Size (Größe im Arbeitsspeicher)
- WCHAN Kernel-Fkt. in der der Prozess schläft (/proc/ksyms)
- STAT Prozessstatus
- R läuft
- S schläft
- D blockiert
- T stopped/traced
- Z "Zombie"
- TTY Controlling TTY
Welche möglichkeiten bieten Prozessgruppen?
- Jeder Prozess ist durch seine Prozessgruppen-ID (PGID) einer Prozessgruppe zugeordnet
- sie kann mit int getpgid(int pid) ermittelt werden
- sie kann mit int setpgid( int pid, int pgid ) gesetzt werden
- PGID wird via fork()/exec*() von seinem Elternprozess vererbt
- Wenn der Prozessgruppenführer terminiert, wird an alle Mitglieder der Prozessgruppe das SIGHUP-Signal gesendet
- Signale können an Prozesse oder Prozessgruppen gesendet werden: kill –SIG_NR <pid> oder kill –SIG_NR -<pgid>
Zusammenfassung: Was sind Prozesse?
- Eine Gruppe von Ressourcen
- Speicher
- Globale Variable
- Filehandles
- Kindprozesse
- Signal-Handler
- Alarme
- Accounting Information
- Ein Ausführungs-Strang ("Thread of Execution")
- Programmzähler, CPU-Register, Stack, Zustand
Was sind Threads und wozu werden sie benötigt?
- Ale Threads innerhalb eines Prozesses teilen sich dieselben Ressourcen
- Speicher, Dateideskriptoren, ...
- Wozu braucht man Threads
- Performance: Quasi-parallele Abarbeitung von Teilaufgaben, die auf denselben Speicher zugreifen
- Bei Rechnern mit mehreren CPUs (SMP) oder CPU-Kernen erlauben Threads effiziente Parallelisierung
Wie werden Threads unter Windows / Unix gehandhabt?
- MS Windows
- Alle Programme sind potenziell multithreaded
- Bei der Erzeugung eines Prozesses wird automatisch der erste Thread erzeugt
- Threads sind die Objekte, die der Scheduler verwaltet
- Unix / Linux
- User-Threads (libpthread)
- Kernel-Threads
Wie lässt sich mit Linux ein pthread erzeugen?
int pthread_create( pthread_t *thread, pthread_attr_t *attr, void *(*start_routine) (void *), void *arg );
- thread Deskriptor für den neuen Thread
- attr Struktur mit Attributen des neuen Threads (pthread-attr_... Fuktionen)
- start_routine Funktion, die der neue Thread zunächst ausführt
- arg Argument für start_routine. Bei mehreren Argumenten Struktur übergeben
Wie wird das wait von Prozessen bei pthreads realisiert?
int pthread_join( pthread_t *thread,void **thread_return );
- sorgt dafür, dass die Ressourcen des Threads wieder freigegeben werden
- thread Deskriptor für den Thread, auf den gewartet werden soll
- thread_return
- Im Fehlerfall: Fehlerbeschreibung
- sonst: Pointer auf *thread