Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 7 Dämonen, Zombies und Prozesse
  gp 7.1 Was ist ein Prozess?
  gp 7.2 Prozesskomponente
    gp 7.2.1 Prozessnummer (PID)
    gp 7.2.2 Prozessnummer des Vaterprozesses (PPID)
    gp 7.2.3 Benutzer- und Gruppennummer eines Prozesses (UID, EUID, GID, EGID)
    gp 7.2.4 Prozessstatus
    gp 7.2.5 Prozesspriorität
    gp 7.2.6 Timesharing-Prozesse
    gp 7.2.7 Prozessauslagerung
    gp 7.2.8 Steuerterminal
  gp 7.3 Prozesse überwachen – ps, top, kpm
  gp 7.4 Lebenszyklus eines Prozesses
  gp 7.5 Umgebungsvariablen eines Prozesses
    gp 7.5.1 Einzelne Umgebungsvariablen abfragen
    gp 7.5.2 Umgebungsvariable verändern oder hinzufügen – putenv() und setenv()
    gp 7.5.3 Löschen von Umgebungsvariablen – unsetenv() und clearenv()
  gp 7.6 Ressourcenlimits eines Prozesses
    gp 7.6.1 Mehr Sicherheit mit Ressourcenlimits
  gp 7.7 Prozesserkennung
  gp 7.8 Erzeugung von Prozessen – fork()
    gp 7.8.1 Pufferung
    gp 7.8.2 Was wird vererbt und was nicht?
    gp 7.8.3 Einen Prozess mit veränderter Priorität erzeugen
  gp 7.9 Warten auf einen Prozess
  gp 7.10 Die exec-Familie
    gp 7.10.1 execl()
    gp 7.10.2 execve()
    gp 7.10.3 execv()
    gp 7.10.4 execle()
    gp 7.10.5 execlp()
    gp 7.10.6 execvp()
    gp 7.10.7 Kindprozesse mit exec-Aufruf überlagern
  gp 7.11 Kommandoaufrufe aus dem Programm – system()
  gp 7.12 Dämonprozesse
    gp 7.12.1 Wie ein Prozess zum Dämon wird ...
    gp 7.12.2 Dämon, sprich mit uns ...
    gp 7.12.3 Protokollieren von Dämonen – syslog()
    gp 7.12.4 syslog() in der Praxis
    gp 7.12.5 Den Dämon, den ich rief ...
  gp 7.13 Rund um die Ausführung von Prozessen
    gp 7.13.1 Einen Dämon beim Booten mit einem init-Skript starten
    gp 7.13.2 Hintergrundprozesse und Jobkontrolle
    gp 7.13.3 Prozesse zeitgesteuert ausführen (cron-Jobs)
  gp 7.14 Zusammenfassung und Ausblick


Rheinwerk Computing

7.4 Lebenszyklus eines Prozesses  toptop

Wenn Sie die vergangenen Seiten mit einer etwas lockereren Haltung gelesen haben, dann sollten Sie jetzt wieder etwas aufmerksamer weiterlesen. Es folgt zwar noch ein wenig Theorie, diese fällt allerdings jetzt mehr in den Bereich Systemprogrammierung als in den der Administration.

Um einen neuen Prozess zu erzeugen, wird der Systemaufruf fork() verwendet. Dieser neu erzeugte Prozess ist dann eine Kopie des aufrufenden Prozesses. Er enthält dieselben Daten, offene Dateien, Lese-/Schreibzeiger, Instruktionszeiger der CPU und auch dieselbe Priorität. Der Prozess, der einen neuen erzeugt (mittels fork()), wird Elternprozess genannt. Da das Geschlecht von Prozessen ungeklärt ist – es gibt sogar Dämonen und Zombies –, bleiben wir bei einem Pluralneutrum (»Elternprozess«). Der neu erzeugte Prozess (die Kopie des Elternprozesses) wird somit als Kindprozess bezeichnet.

Der neu erzeugte und gestartete Kindprozess (genauer: fork()) liefert dem Elternteil bei Erfolg gleich seine Prozessnummer (PID) zurück. Der Kindprozess hingegen bekommt die 0 von fork() zurückgegeben. Jetzt laufen beide Prozesse unabhängig voneinander und asynchron weiter.

Soll ein nicht identischer neuer Prozess gestartet werden, können Sie nach der Erzeugung dieses Prozesses im Kindprozess einen exec-Systemaufruf machen. Bei einem exec-Aufruf werden die einzelnen Segmente (s. o.) des aufrufenden Prozesses durch die des neuen Prozesses ersetzt. Der überlagerte neue Prozess behält allerdings die PID des aufrufenden Prozesses und alle Filedeskriptoren, bei denen nicht das close-on-exec-Flag gesetzt wurde (siehe Kap. 2). Diese Art, aus einer Anwendung eine andere Anwendung (Prozess) zu starten, wird häufig verwendet. Es gibt mehrere Formen der exec-Familie, die sich nur geringfügig voneinander unterscheiden. Die wohl bekannteste Funktion ist system(), die den ganzen Prozess einheitlich macht; aber dazu siehe mehr unten.

Beim Starten des Systems werden vom Kernel einige Prozesse selbstständig erzeugt. Der wichtigste davon ist init (mit der PID 1), der Ursprung aller Prozesse. init ist verantwortlich für die Ausführung von Startup-Skripten. Alle anderen, nicht vom Kernel erzeugten Prozesse sind Kindprozesse von init. Einen Überblick über die »Prozesshierarchie« können Sie sich mit dem Kommando pstree oder einem der vielen grafischen Frontends verschaffen.

$ pstree -p | less
init(1)-+-atd(632)
        |-bdflush(5)
        |-cardmgr(1201)
        |-cron(1540)
        |-kalarmd(1967)
        |-kdeinit(1882)-+-artsd(1906)
        |               |-kdeinit(1914)
        |               |-kdeinit(1942)-+-bash(1949)
        |               |               `-bash(1951)---pstree(2586)
        |               |-kdeinit(1947)
        |               |-kdeinit(1959)
        |               |-kdeinit(2246)
...

init spielt eine große Rolle in der Prozessverwaltung. Ein Prozess, der sich freiwillig beendet, benutzt exit(). Ein Prozess, der nicht freiwillig beendet wird, z. B. durch ein Signal, ruft zuerst den libc-Sighandler (sofern nicht ein anderer eingerichtet wurde) auf (der dann z. B. »Segmentation Fault« printet, bevor er abbricht) und dann das Unterstrich-_exit(). _exit() ist allein für den Switch zum Kernelspace verantwortlich und beachtet nicht die Schließung von stdin etc.

Wird der Elternprozess vor dem Kindprozess beendet, so übernimmt init die Patenschaft für das Waisenkind. Beendet sich der Kindprozess (bzw. wird beendet), so werden alle Ressourcen, wie z. B. noch offene Dateien oder belegter Speicher, freigegeben. Die weitere Beendigung des Prozesses wird wieder in die Hand des Elternteils, was auch init sein kann, gegeben. An den Elternprozess wird das Signal SIGCHLD gesendet, das signalisiert, dass der Prozess beendet wurde. Dies allein trägt jedoch den beendeten Prozess noch nicht aus der Tabelle aus, dafür muss der Elternprozess noch die Funktion wait() aufrufen.

Wird der Elternprozess partout nicht über den Verbleib seines Kindes in Kenntnis gesetzt (wurde z. B. »vergessen«, wait() aufzurufen) und beendet sich dieser, wird der Kindprozess als Zombie bezeichnet.


Hinweis   Zombie ist der Zustand, den ein Prozess hat, nachdem dieser sich beendet hat, aber noch nicht durch den Elternprozess ge»wait«et() wurde. Man kann daher nicht sagen, dass ein Prozess vergessen wurde, nur weil wait() noch nicht aufgerufen wurde.

Der Cron-Dämon z. B. klappert alle prozessbezogenen Ereignisse nur in 60s-Intervallen ab, weshalb man dort des Öfteren defunct sieht.


In der Liste des ps-Kommandos finden Sie einen Zombie-Zustand als <defunct> und im »STAT«-Feld mit »Z« gekennzeichnet. Das bedeutet im Klartext, dass der Prozess beendet, jedoch noch nicht aufgeräumt wurde (s. o.).

Natürlich ist dies jetzt nicht die gesamte Theorie zu den Prozessen. Insbesondere Themen wie die Kommunikation und Synchronisation von Prozessen wurden noch nicht angesprochen. Dem werden wir uns in einem anderen Kapitel zuwenden (Signale, Kapitel 7, und IPC, Kapitel 8). Da Sie jetzt Kenntnisse zu den Prozessen besitzen, will ich mit der Praxis beginnen.

 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern