Diskussion:Linux/Prozesse: Unterschied zwischen den Versionen

Aus Foxwiki
Thomaskarras (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Thomaskarras (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
== Ohne direkten Kontakt ==


    Die bisher vorgestellten Fälle betrachteten nur die Möglichkeit, Programme während einer Sitzung parallel von einer Shell aus zu starten, und im Hintergrund ablaufen zu lassen.
    Interessant ist aber auch der Weg, Programme auf der Shell zu starten, und diese nach dem Abmelden, sprich dem Beenden der benutzten Shell, weiter laufen zu lassen.
    Bisher waren in allen Beispielen die gestarteten Programme an die aufrufende Shell gebunden. So dass bei Beendigung selbiger auch die an sie gebundenen Prozesse den Aufruf zum Beenden erhalten.
    Um Programme von der Shell abzukoppeln, wird das Kommando nohup verwendet.
    Dieses schirmt das Programm vom HUP-Signal der Shell ab, so dass es nach dem Beenden der Shell unabhängig weiter laufen kann:
nohup ls -lR / >/dev/null &
[1] 2511
ps -ef | grep 2511
user    2511  2502 20 00:28 tty5    00:00:02 ls -lR /
user    2514  2502  0 00:28 tty5    00:00:00 grep 2511
exit
...auf einer anderen oder neuen Shell:
Have a lot of fun...
ps -ef | grep 2511
user    2511    1 14 00:28 ?      00:00:05 ls -lR /
user    2524  2516  0 00:29 tty5    00:00:00 grep 2511
nohup startet das Programm nicht selbstständig im Hintergrund.
    So ist es möglich, ein Programm analog zum »normalen« Vorgehen (ohne »nohup«) zu starten, eventuell notwendige Eingaben vorzunehmen und erst im Anschluss das Programm durch Eingaben von [Ctrl]-[Z] und nachfolgendem bg in den Hintergrund zu schicken.
    Erst jetzt existiert der das Programm ausführende Prozess tatsächlich abgenabelt von seinem Vorfahren.
    Ein Prozess, der keine Eingaben benötigt, lässt sich bequem durch ein der Kommandozeile nachgestelltes & unverzüglich vom Elternprozess entkoppeln.
    Und welche Möglichkeiten bleiben mir nun, um solch einen Prozess nachträglich zu beeinflussen?
    Eine direkte Verbindung zum Terminal wie bei fg ist nicht mehr möglich. Hier hilft nur noch eine indirekte Kommunikation über Signale, die u.a. mit dem Kommando kill übermittelt werden können:
dd if=/dev/zero of=/dev/null &
[1] 20098
   
   
ps -axuw | grep 20098
== Entstehen und Vergehen ==
user    20098 30.5  0.3  1204  448 pts/4    R    11:49  0:36 dd if=/dev/zero of=/dev/null
kill -19 20098
ps -axuw | grep 20098
user    20098 75.9  0.3  1204  448 pts/4    T    11:49  1:01 dd if=/dev/zero of=/dev/null
kill -18 20098
ps -axuw | grep 20098
user    20098 55.5  0.3  1204  448 pts/4    R    11:49  1:54 dd if=/dev/zero of=/dev/null
kill -15 20098


Erläuterung
Ein Prozess entsteht, indem ein Elternprozess mittels des Systemrufes fork() einen neuen Prozess erzeugt (Ausnahme ist init, der einzige "von Hand generierte" Prozess). Dieser Kindprozess teilt sich alle Ressourcen mit dem Elternprozess, wesentliche Unterschiede sind nur ein eigener Stack und eine eigene PID.


     Das Kommando »dd« (zum »Low-Level«-Kopieren) wird im Hintergrund gestartet. Dass es aktiv ist, bestätigt das »R« (running) in der Ausgabe des Kommandos ps. In einer weiteren Eingabe wird dem Prozess die Aufforderung zum Stoppen signalisiert (Signal Nr. 19).
     Anhand des Rückgabewertes von fork() ist es den beiden Prozessen nun möglich, zu unterscheiden, ob es sich um den Vorfahren oder einen Nachkommen handelt.
     Dass es tatsächlich funktioniert hat, beweist nun das »T« (traced oder gestoppt) in der »ps«-Ausgabe.
    In Abhängigkeit hiervon wird nun ein Kindprozess mittels des Systemrufes exec() ein neues Programm laden.
     Mit dem Signal 18 schließlich wird der Prozess reaktiviert; das »R« ist wieder in der Ausgabe zu sehen.
    Irgendwann wird ein Kindprozess seine Arbeit beenden und signalisiert diesen Zustand seinem Elternprozess durch eine entsprechende Nachricht.
     Damit unser Beispielkommando nicht für alle Zeit die Nullen in den Mülleimer befördert, brechen wir es mit dem Signal 15 (Aufforderung zum Beenden) ab.
    Obwohl der Kindprozess bereits jetzt aus Speicher und Prozesstabelle entfernt ist, muss dieses Signal noch verarbeitet werden. Für gewöhnlich zeichnet der Elternprozess dafür verantwortlich.
     Zwei Situationen könnten den "normalen Werdegang" durcheinander bringen:
    Der Elternprozess ist andersweitig beschäftigt (befindet sich im Zustand D o.a.).
     In einem solchen Fall symbolisiert der Zustand Z das noch zu behandelnde Signal. Genau genommen durchläuft jeder Kindprozess die Laufbahn eines Zombies (Zeitspanne zwischen Ableben und Signalbehandlung), jedoch ist sie meist von so kurzer Dauer, dass man gar nichts davon mitbekommt.
     Der Elternprozess existiert nicht mehr (Programmfehler o.a.). Jetzt ist der init-Prozess für der Signalbehandlung verantwortlich

Version vom 16. Oktober 2020, 09:39 Uhr


Entstehen und Vergehen

Ein Prozess entsteht, indem ein Elternprozess mittels des Systemrufes fork() einen neuen Prozess erzeugt (Ausnahme ist init, der einzige "von Hand generierte" Prozess). Dieser Kindprozess teilt sich alle Ressourcen mit dem Elternprozess, wesentliche Unterschiede sind nur ein eigener Stack und eine eigene PID.

   Anhand des Rückgabewertes von fork() ist es den beiden Prozessen nun möglich, zu unterscheiden, ob es sich um den Vorfahren oder einen Nachkommen handelt.
   In Abhängigkeit hiervon wird nun ein Kindprozess mittels des Systemrufes exec() ein neues Programm laden.
   Irgendwann wird ein Kindprozess seine Arbeit beenden und signalisiert diesen Zustand seinem Elternprozess durch eine entsprechende Nachricht.
   Obwohl der Kindprozess bereits jetzt aus Speicher und Prozesstabelle entfernt ist, muss dieses Signal noch verarbeitet werden. Für gewöhnlich zeichnet der Elternprozess dafür verantwortlich.
   Zwei Situationen könnten den "normalen Werdegang" durcheinander bringen:
   Der Elternprozess ist andersweitig beschäftigt (befindet sich im Zustand D o.a.).
   In einem solchen Fall symbolisiert der Zustand Z das noch zu behandelnde Signal. Genau genommen durchläuft jeder Kindprozess die Laufbahn eines Zombies (Zeitspanne zwischen Ableben und Signalbehandlung), jedoch ist sie meist von so kurzer Dauer, dass man gar nichts davon mitbekommt.
   Der Elternprozess existiert nicht mehr (Programmfehler o.a.). Jetzt ist der init-Prozess für der Signalbehandlung verantwortlich