GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Überblick über UNIX-Prozesse (innerhalb eines Linux-Prozesses und Prozesstypen)

Ein Prozess ist eine laufende Instanz eines Programms. In diesem Artikel haben wir zwei Begriffe „Programm“ und „laufende Instanz“ verwendet. Angenommen, wir führen ein Programm fünfmal gleichzeitig aus, dann wird für jede Instanz ein Prozess im System ausgeführt. Wir sagen also, dass ein Prozess eine „laufende Instanz“ eines Programms ist.

Wie Sie bereits wissen, können Sie den Befehl ps verwenden, um die auf Ihrem System laufenden Prozesse anzuzeigen. Informationen zur effektiven Verwendung des Befehls ps finden Sie unter 7 praktische Beispiele für PS-Befehle zur Prozessüberwachung.

1. Einblick in einen Prozess

Nun, da wir uns darüber im Klaren sind, was genau ein Prozess ist, wollen wir etwas tiefer gehen, um zu sehen, woraus ein Prozess besteht. Ein Unix-Prozess kann als Container betrachtet werden, der Folgendes enthält:

Programmanleitung

Programmanweisungen werden in Textsegmenten gehalten, die von der CPU ausgeführt werden. Normalerweise wird bei Programmen wie Texteditoren, die häufig ausgeführt werden, das Textsegment geteilt. Dieses Segment hat nur Leserechte, was bedeutet, dass ein Programm sein Textsegment nicht ändern kann.

Daten

Meistens werden die Daten im Datensegment gehalten. Datensegmente können in initialisierte Datensegmente und nicht initialisierte Datensegmente eingeteilt werden. Wie der Name schon sagt, enthält das initialisierte Datensegment diejenigen globalen Variablen, die zuvor initialisiert wurden, während das nicht initialisierte Datensegment (auch als „BSS“-Segment bekannt) nicht initialisierte globale Variablen enthält. Außerdem werden statische Variablen im Datensegment gespeichert.

Lokale Variablen, die für Funktionen lokal sind, werden auf dem Stack gespeichert. Stack ist für eine Funktion spezifisch und enthält neben den Informationen über lokale Variablen auch Informationen über die Adresse, an die der Fluss zurückkehrt, sobald die Ausführung der Funktion abgeschlossen ist. Stack enthält auch Informationen über die Umgebung des Aufrufers, da einige der Maschinenregister auch im Stack gespeichert sind. Eine aufgerufene Funktion weist Speicher für ihre lokalen Variablen und temporären Variablen auf dem Stack selbst zu. Bei rekursiven Funktionen existiert ein unabhängiger Stack für jeden Funktionsaufruf.

Dann gibt es Daten, die auf dem Haufen gespeichert werden. Dieser Speicher für diese Daten wird zur Laufzeit auf dem Heap-Segment allokiert. Das Heap-Segment ist nicht lokal für einen Prozess, sondern wird von allen Prozessen gemeinsam genutzt. Das ist der Grund, warum C-Programmierer sich viele Gedanken über Speicherlecks machen, die auf Heap-Segmenten verursacht werden und andere Prozesse auf dem System beeinträchtigen können.

Befehlszeilenargumente und Umgebungsvariablen

Ein Prozess enthält auch Platz zum Speichern von Umgebungsvariablen und der Befehlszeilenargumente, die wir an das Programm übergeben. Normalerweise wird der Vektor, der die Befehlszeileninformationen enthält, hier gespeichert, und dann wird die Adresse dieses Informationsvektors und die Anzahl der Elemente im Vektor nach 'argv' und 'argc' kopiert (die beiden Argumente der Funktion 'main()').

Neben den oben genannten Informationen enthält ein Prozess auch Informationen wie

  • Status seiner E/A
  • Seine Priorität und andere Kontrollinformationen

Eine der wichtigsten Steuerinformationen für einen Prozess sind die Privilegien. Ein Prozess erbt direkt alle Privilegien des Benutzers, der diesen Prozess ausgelöst hat. Beispielsweise kann ein Prozess, der von einem Benutzer ohne Superuser-Rechte ausgelöst wird, keine Dinge tun, die Root-Rechte erfordern, während ein von Root ausgelöster Prozess alles tun kann, wofür er programmiert ist. Eine Ausnahme von der obigen Regel ist, wenn ein Prozess größere Privilegien erwerben kann als der Benutzer, der ihn ausgelöst hat, wenn das setuid- oder setgid-Bit für diesen bestimmten Prozess gesetzt ist. Aber wir werden hier nicht sehr ins Detail gehen (weitere Informationen dazu finden Sie in den Manpages von setuid und setgid).

2. Hintergrund- und Vordergrundprozesse

Wie wir bereits besprochen haben, können wir einen Prozess mit seinem Namen in Unix starten. Wie einige Standardprogramme können „ls“, „ps“ usw. gestartet werden, indem einfach ihr Name am Shell-Prompt eingegeben wird. Es gibt zwei Möglichkeiten, wie wir einen Prozess starten können

  • Im Vordergrund beginnen
  • Start im Hintergrund

Angenommen, es gibt ein Dienstprogramm, das einige Zeit verbraucht und eine Zählung durchführt. Nehmen wir an, der Name des Dienstprogramms ist „count“. Um das Programm im Vordergrund auszulösen und auszuführen, führe ich den folgenden Befehl aus (wobei „count“ der Name der Binärdatei aus dem obigen Code ist):

$ ./count
Counting done

Wir sehen also, dass es nach dem Ausführen der Binärdatei „./count“ fast 10 Sekunden dauerte, bis die Ausgabe auf stdout angezeigt wurde, und bis dahin war die Shell nur von diesem Prozess belegt. dh Sie könnten keine andere Operation auf derselben Shell ausführen. Um nun einen Prozess im Hintergrund auszulösen, fügen Sie am Ende des Befehls „&“ hinzu:

$ ./count &
[1] 4120

$ # Do some work on shell while the above program is working in the background

$ Counting done

Das kaufmännische Und-Zeichen „&“ zeigt an, dass dieser Prozess als Hintergrundprozess ausgeführt werden muss. Durch Ausführen eines Hintergrundprozesses können wir auf die Shell zugreifen, um weitere Vorgänge auszuführen. Wie in der obigen Ausgabe habe ich nach dem Ausführen des binären „count“ im Hintergrund ein paar weitere Befehle auf derselben Shell verwendet, und als der binäre „count“ mit seiner Verarbeitung fertig war, wurde die Ausgabe auf dieselbe Shell zurückgeworfen (die letzte Zeile). Wir können also schließen, dass standardmäßig jeder Prozess im Vordergrund läuft, Eingaben (falls vorhanden) von der Tastatur erhält und Ausgaben an den Benutzer zurückgibt. Während ein Hintergrundprozess von der Tastatur getrennt wird und der Benutzer dieselbe Shell verwenden kann, um weitere Operationen auszuführen.

Weitere Informationen zu Vordergrund- und Hintergrundprozessen finden Sie unter:How to Manage UNIX Background Jobs

3. Arten von Prozessen

Wir sehen also, dass Prozess ein Konzept ist, das für ein Betriebssystem grundlegend ist. Fast jede Aktivität auf einem Betriebssystem nimmt die Form eines Prozesses an, um etwas zu tun. Es gibt verschiedene Arten von Prozessen, die auf einem System laufen, einige davon sind :

Untergeordnete Prozesse

Ein Prozess, der während der Laufzeit von einem anderen Prozess erstellt wird. Normalerweise werden untergeordnete Prozesse erstellt, um Binärdateien innerhalb eines vorhandenen Prozesses auszuführen. Untergeordnete Prozesse werden mit dem Systemaufruf fork() erstellt. Normalerweise laufen Prozesse über Shell/Terminal. In diesem Fall wird die Shell zum Elternprozess und der ausgeführte Prozess zum Kindprozess. Unter Unix/Linux hat jeder Prozess einen Elternprozess, mit Ausnahme des Init-Prozesses (wir werden später mehr darüber erfahren).

Daemon-Prozesse

Dies sind spezielle Prozesse, die im Hintergrund ausgeführt werden. Sie sind systembezogene Prozesse, denen kein Terminal zugeordnet ist. Diese ausgeführten Prozesse erhalten Root-Berechtigungen und stellen normalerweise Dienste für Prozesse bereit. Da wir bereits wissen, dass ein Daemon-Prozess kein angeschlossenes Terminal hat, muss der Prozess dazu vom Terminal getrennt werden. Der ideale Weg unter Linux/Unix, dies zu tun, besteht darin, einen Prozess über das Terminal auszuführen und innerhalb dieses Prozesses einen anderen Prozess zu erstellen und dann den übergeordneten Prozess zu beenden. Da der Elternprozess nun beendet wird, wird der Kindprozess unabhängig vom Terminal und würde vom Init-Prozess übernommen und würde somit zu einem Daemon-Prozess. Ein typisches Beispiel wäre ein Mail-Daemon, der auf das Eintreffen von E-Mails wartet und benachrichtigt, wenn eine E-Mail eintrifft.

Verwaiste Prozesse

Normalerweise erstellt ein Prozess einen untergeordneten Prozess (wie oben beschrieben), und wenn der untergeordnete Prozess beendet wird, wird ein Signal an den übergeordneten Prozess ausgegeben, damit der übergeordnete Prozess alles tun kann, was er tun muss, wenn einer der untergeordneten Prozesse beendet wird. Aber es gibt Situationen, in denen ein Elternteil getötet wird. In diesem Fall werden die untergeordneten Prozesse verwaist und dann vom Init-Prozess übernommen. Obwohl der Init-Prozess den Besitz des verwaisten Prozesses übernimmt, werden diese Prozesse dennoch als verwaiste Prozesse bezeichnet, da ihre ursprünglichen Eltern nicht mehr existieren.

Zombie-Prozess

Wenn ein untergeordneter Prozess beendet wird oder seine Ausführung abschließt, bleibt sein Eintrag in der Prozesstabelle bestehen, bis der übergeordnete Prozess die Statusinformationen des beendeten untergeordneten Prozesses abruft. Bis dahin tritt der beendete Prozess in den Zombie-Zustand ein und wird als Zombie-Prozess bezeichnet. Wenn ein Prozess beendet wird, werden alle dem Prozess zugeordneten Speicher und Ressourcen freigegeben, aber der Eintrag des Prozesses in der Prozesstabelle existiert. Ein Signal SIGCHILD wird an den Elternprozess (der gerade beendet wurde) gesendet. Typischerweise führt der Handler dieses Signals im Elternteil einen „Wait“-Aufruf aus, der den Exit-Status des beendeten Prozesses abruft, und dann wird auch der Eintrag dieses Zombie-Prozesses aus der Prozesstabelle entfernt.

4. Der Init-Prozess

Wie wir bereits besprochen haben, ist der Init-Prozess die 5. Stufe in der 6. Stufe des Linux-Boot-Prozesses.

Sie würden die berühmte „Henne und Ei“-Theorie darüber kennen, wer zuerst da war. Da jeder Prozess einen übergeordneten Prozess hat, kann die gleiche Frage zu übergeordneten oder untergeordneten Prozessen gestellt werden. Nun, zum Glück gibt es hier eine Antwort. Die Antwort ist der Init-Prozess, der als erster Prozess während der Boot-Sequenz gestartet wird. Das bedeutet, dass es keinen Elternprozess des Init-Prozesses gibt. Lassen Sie uns das überprüfen, da die PID von init „1“ ist, verwenden wir den Befehl ps :

Wir sehen also an der Ausgabe, dass PPID 0 ist, was bedeutet, dass es keinen Elternprozess für diesen Prozess gibt.

$ ps -l 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
4 S     0     1     0  0  80   0 -  5952 poll_s ?          0:00 /sbin/init

Die folgenden sind einige der Befehle, die sich mit Prozessen befassen:Top-Befehl, HTOP-Befehl, PS-Befehl, Kill-Befehl (pkill, xkill).


Linux
  1. Linux-Befehle – Übersicht und Beispiele

  2. So finden und töten Sie den Zombie-Prozess in Linux

  3. Linux – Standard- und/oder gemeinsame Verzeichnisse auf Unix/Linux-Betriebssystemen?

  4. 12 Schritte zum Installieren und Konfigurieren von Alfresco unter UNIX / Linux

  5. mmap-, msync- und Linux-Prozessbeendigung

Unix- und Linux-Geschichte

Linux gegen Unix

Zip- und Unzip-Befehle unter Linux/Unix

Übersicht über verteilte Datenbanktypen und Sicherheit

Überblick über RAMFS und TMPFS unter Linux

So verfolgen und verfolgen Sie einen Linux-Prozess