Wann sollte man fork () und exec () alleine aufrufen?

9

Ich lerne etwas über die Befehle fork () und exec (). Es scheint, als würden fork () und exec () normalerweise zusammen aufgerufen. (fork () erstellt einen neuen untergeordneten Prozess und exec () ersetzt das aktuelle Prozessabbild durch ein neues.) In welchen Szenarien können Sie jedoch jede Funktion für sich aufrufen? Gibt es solche Szenarien?

quil
quelle
2
Traditionelle Gabelbombe: while (1) Gabel (); Systemressourcen zu belasten.
Joshua

Antworten:

22

Sicher! Ein übliches Muster in "Wrapper" -Programmen besteht darin, verschiedene Dinge zu tun und sich dann durch ein anderes Programm zu ersetzen, das nur einen execAufruf enthält (keine Gabelung).

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

Ein reales Beispiel hierfür ist GIT_SSH( git(1)bietet jedoch auch, GIT_SSH_COMMANDwenn Sie die oben beschriebene Wrapper-Programmmethode nicht ausführen möchten).

Fork-only wird verwendet, wenn eine Reihe von typischen Worker-Prozessen erzeugt werden (z. B. Apache httpdim Fork-Modus (obwohl Fork-only besser für Prozesse geeignet ist, die die CPU verbrennen müssen, und nicht für Prozesse, die mit den Daumen drehen und auf Netzwerk-E / A warten). ) oder zur Privilegientrennung, die von sshdund anderen Programmen unter OpenBSD verwendet wird (keine Ausführung)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

Der rootsshd hat auf der Clientverbindung eine Kopie von sich selbst (28571) und dann eine weitere Kopie (14625) für die Privilegientrennung abgezweigt.

Thrig
quelle
14

Es gibt viele.

Programme, die fork()ohne aufrufen, exec()folgen normalerweise einem Muster von Laichprozessen für untergeordnete Mitarbeiter, um verschiedene Aufgaben in separaten Prozessen zum Hauptprozess auszuführen. Sie finden diese in den Programmen finden wie variiert dhclient, php-fpmund urxvtd.

Ein Programm , das Anruf exec()ohne fork()ist Kettenbelastung , seinen Prozess mit einem anderen Programmbild überlagert. Es gibt eine ganze Subkultur von Dienstprogrammen zum Laden von Ketten, die bestimmte Aktionen ausführen, um den Status zu verarbeiten und dann ein anderes Programm auszuführen, das mit diesem überarbeiteten Prozessstatus ausgeführt wird. Solche Dienstprogramme sind in der daemontools-Familie von Service- und Systemverwaltungs-Toolsets üblich, aber nicht auf diese beschränkt. Einige Beispiele:

Die Toolsets der Daemontools-Familie verfügen über viele solcher Tools, von machineenvbis find-matching-jvmbis runtool.

JdeBP
quelle
2

Zusätzlich zu anderen Antworten nutzen Debugger, die verwenden ptrace, normalerweise die Lücke zwischen forkund exec. Ein Debugger sollte sich mit markieren, PTRACE_TRACEMEum anzuzeigen, dass er von seinem übergeordneten Prozess - dem Debugger - verfolgt wird. Dies dient dazu, dem Debugger die erforderlichen Berechtigungen zu erteilen.

Ein Debugger würde sich also zuerst selbst teilen. Das Kind würde rufen Sie ptracemit PTRACE_TRACEMEund rufen Sie dann exec. Welches Programm auch immer die untergeordneten Execs ausführen, sie können jetzt vom übergeordneten Programm nachverfolgt werden.

Bytefire
quelle
Es gibt viele Beispiele für das Ausführen von Dingen zwischen Fork und Exec. Das häufigste ist das Umleiten von E / A (z. B. das Einrichten von Pipes). Aber die Frage ist, Gabel ohne Exec überhaupt zu machen.
Barmar
0

Exec ohne Gabel

Es gibt mindestens zwei Gründe, warum Sie so etwas tun möchten:

  1. Kettenladen. Das aktuelle Prozessabbild wird durch etwas anderes ersetzt.
  2. Neustart des aktuell ausgeführten Programms (kann zum Beispiel passieren, wenn Sie SIGHUP oder einen solchen Serverprozess durchführen, alles neu laden und einen völlig neuen Start durchführen). In gewisser Weise könnte man argumentieren, dass dies Kettenladen ist, nur zufällig mit demselben Programm.

Gabel ohne Exec

Das macht jeder Daemon jedes Mal, wenn er gestartet wird (tatsächlich zweimal). Dies führt verschiedene Aktionen aus, darunter, dass die Shell nicht hängt (da der ursprüngliche Prozess, auf den die Shell wartet, beendet wird) und der Dämon nicht mehr vom Terminal gesteuert wird, sodass das Schließen des Shell-Fensters den Dämon nicht beendet.

Eine andere häufige Verwendung ist das Gabeln von Arbeiterkindern, das vor etwa 25 Jahren durch den Apache-Webserver berühmt wurde (heutzutage wird dies nicht mehr als Stand der Technik angesehen, da es sehr anfällig für das Problem der donnernden Herde ist, aber es bietet sicher das verdammt einfachster, robustester Server möglich).

Eine weitere häufige Verwendung besteht darin, einen konsistenten Schnappschuss zu erstellen. forkerstellt nicht nur einen Prozess, sondern kopiert auch den Adressraum (theoretisch markiert er nur Seiten, die beim Schreiben kopiert werden). Dadurch wird (atomar) eine Momentaufnahme der gesamten Programmdaten erstellt, die das übergeordnete Element nicht mehr ändern kann.
Einige Programme nutzen dies aus. Zum Beispiel speichert redis Daten auf der Festplatte (in einem konsistenten Zustand) und ändert gleichzeitig den Datensatz. Dies funktioniert nur, weil forkein konsistenter Snapshot erstellt wurde, in dem die vom übergeordneten Prozess vorgenommenen Änderungen nicht angezeigt werden.

Damon
quelle
Es sind heutzutage nur sehr wenige Dæmons, wobei die meisten dies nicht als Standard tun oder einen häufig verwendeten Modus haben, dies nicht zu tun. Es ist ein Fehler , zu Gabel zu führenden Bereitschaft Mismatch und Schrecken , und ist einer der Fehler , der dem dæmonization Trugschluss . Dieser Fehler ist endlich weitgehend in Ungnade gefallen.
JdeBP