Manpages sind in der Regel knappe Referenzdokumente. Wikipedia ist ein besserer Ort für konzeptionelle Erklärungen.
Fork dupliziert einen Prozess: Es wird ein untergeordneter Prozess erstellt, der fast identisch mit dem übergeordneten Prozess ist (der offensichtlichste Unterschied besteht darin, dass der neue Prozess eine andere Prozess-ID hat). Insbesondere muss fork (konzeptionell) den gesamten Speicher des übergeordneten Prozesses kopieren.
Da dies ziemlich kostspielig ist, wurde vfork erfunden, um einen allgemeinen Sonderfall zu behandeln, bei dem die Kopie nicht erforderlich ist. Oft ist das erste, was der untergeordnete Prozess tut, ein neues Programm-Image zu laden. Das passiert also:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
Der execve
Aufruf lädt ein neues ausführbares Programm, und dies ersetzt den Code und den Datenspeicher des Prozesses durch den Code der neuen ausführbaren Datei und einen neuen Datenspeicher. Die gesamte von erstellte Speicherkopie fork
war also alles für nichts.
So wurde der vfork
Ruf erfunden. Es wird keine Kopie des Speichers erstellt. Daher vfork
ist es billig, aber es ist schwierig zu verwenden, da Sie sicherstellen müssen, dass Sie nicht auf den Stapel- oder Heapspeicher des Prozesses im untergeordneten Prozess zugreifen. Beachten Sie, dass auch das Lesen ein Problem sein kann, da der übergeordnete Prozess weiterhin ausgeführt wird. Dieser Code ist beispielsweise fehlerhaft (funktioniert möglicherweise nicht, je nachdem, ob das Kind oder das Elternteil zuerst eine Zeitscheibe erhält):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Seit der Erfindung von vfork wurden bessere Optimierungen erfunden. Die meisten modernen Systeme, einschließlich Linux, verwenden eine Form von Copy-on-Write , bei der die Seiten im Prozessspeicher nicht zum Zeitpunkt des fork
Aufrufs kopiert werden , sondern später, wenn das über- oder untergeordnete Element zum ersten Mal auf die Seite schreibt. Das heißt, jede Seite beginnt als freigegeben und bleibt freigegeben, bis ein Prozess auf diese Seite schreibt. Der schreibende Prozess erhält eine neue physische Seite (mit derselben virtuellen Adresse). Copy-on-Write macht vfork zumeist unbrauchbar, da fork
in den Fällen, in denen vfork
es brauchbar wäre , keine Kopie erstellt wird .
Linux behält vfork bei. Der fork
Systemaufruf muss weiterhin eine Kopie der virtuellen Speichertabelle des Prozesses erstellen, auch wenn der tatsächliche Speicher nicht kopiert wird. vfork
braucht das nicht einmal zu tun. Die Leistungsverbesserung ist in den meisten Anwendungen vernachlässigbar.
fork
muss eine separate Zuordnung des virtuellen Speichers erstellen, damit nachfolgende Copy-on-Write-Kopien nur einen der beiden Prozesse betreffen.Die
fork()
undvfork()
Syscalls sind unterschiedlich.Der
fork()
Syscall generiert zwei identische Prozesse mit separatem Speicher. Dervfork()
Syscall generiert zwei Prozesse, die sich denselben Speicher teilen.Mit
vfork()
dem Elternteil wird gewartet, bis das Kind abbricht. Das übergeordnete Element erbt von den Variablen, die das Programm gemeinsam nutzt. Nachdem das untergeordnete Element aufgerufen wurde, werden alle im untergeordneten Element geänderten Variablen weiterhin im übergeordneten Element geändert.Weitere Informationen finden Sie hier
quelle