Ich habe nach dem Unterschied zwischen diesen vier bei Google gesucht und erwartet, dass es eine große Menge an Informationen dazu gibt, aber es gab wirklich keinen soliden Vergleich zwischen den vier Anrufen.
Ich habe versucht, eine Art grundlegenden Überblick über die Unterschiede zwischen diesen Systemaufrufen zu erhalten, und hier ist, was ich bekommen habe. Sind alle diese Informationen korrekt / fehlt mir etwas Wichtiges?
Fork
: Der Fork-Aufruf erstellt im Grunde genommen ein Duplikat des aktuellen Prozesses, das in fast jeder Hinsicht identisch ist (in einigen Implementierungen wird nicht alles kopiert, z. B. Ressourcenbeschränkungen, aber die Idee ist, eine möglichst enge Kopie zu erstellen).
Der neue Prozess (untergeordnet) erhält eine andere Prozess-ID (PID) und hat die PID des alten Prozesses (übergeordnet) als übergeordnete PID (PPID). Da die beiden Prozesse jetzt genau denselben Code ausführen, können sie anhand des Rückkehrcodes von fork erkennen, welcher Code welcher ist - das Kind erhält 0, das Elternteil erhält die PID des Kindes. Dies alles ist natürlich vorausgesetzt, dass der Fork-Aufruf funktioniert. Wenn nicht, wird kein untergeordnetes Element erstellt und das übergeordnete Element erhält einen Fehlercode.
Vfork
: Der grundlegende Unterschied zwischen vfork und fork besteht darin, dass beim Erstellen eines neuen Prozesses mit vfork () der übergeordnete Prozess vorübergehend angehalten wird und der untergeordnete Prozess möglicherweise den Adressraum des übergeordneten Prozesses ausleiht. Dieser seltsame Zustand setzt sich fort, bis der untergeordnete Prozess entweder beendet wird oder execve () aufruft. An diesem Punkt wird der übergeordnete Prozess fortgesetzt.
Dies bedeutet, dass der untergeordnete Prozess einer vfork () vorsichtig sein muss, um zu vermeiden, dass Variablen des übergeordneten Prozesses unerwartet geändert werden. Insbesondere darf der untergeordnete Prozess nicht von der Funktion zurückkehren, die den Aufruf von vfork () enthält, und er darf nicht exit () aufrufen (wenn er beendet werden muss, sollte er _exit () verwenden; dies gilt tatsächlich auch für das untergeordnete Element einer normalen Gabel ()).
Exec :
Der Exec-Aufruf ist eine Möglichkeit, den gesamten aktuellen Prozess durch ein neues Programm zu ersetzen. Es lädt das Programm in den aktuellen Prozessbereich und führt es vom Einstiegspunkt aus. exec () ersetzt den aktuellen Prozess durch die ausführbare Datei, auf die die Funktion zeigt. Die Steuerung kehrt niemals zum ursprünglichen Programm zurück, es sei denn, es liegt ein exec () - Fehler vor.
Clone :
Klonen als Gabel erzeugt einen neuen Prozess. Im Gegensatz zu Fork ermöglichen diese Aufrufe dem untergeordneten Prozess, Teile seines Ausführungskontexts mit dem aufrufenden Prozess zu teilen, z. B. den Speicherplatz, die Tabelle der Dateideskriptoren und die Tabelle der Signalhandler.
Wenn der untergeordnete Prozess mit dem Klon erstellt wird, führt er die Funktionsanwendung fn (arg) aus. (Dies unterscheidet sich von Fork, bei dem die Ausführung im untergeordneten Element ab dem Zeitpunkt des ursprünglichen Fork-Aufrufs fortgesetzt wird.) Das Argument fn ist ein Zeiger auf eine Funktion, die vom untergeordneten Prozess zu Beginn seiner Ausführung aufgerufen wird. Das Argument arg wird an die Funktion fn übergeben.
Wenn die Funktionsanwendung fn (arg) zurückkehrt, wird der untergeordnete Prozess beendet. Die von fn zurückgegebene Ganzzahl ist der Exit-Code für den untergeordneten Prozess. Der untergeordnete Prozess kann auch explizit durch Aufrufen von exit (2) oder nach Empfang eines schwerwiegenden Signals beendet werden.
Informationen erhalten Form:
- Unterschiede zwischen Gabel und Exec
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2_clone.htm
Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu lesen! :) :)
fork()
ist als unter Linux und wahrscheinlich allen BSDs) den Adressraum seiner Eltern ausleiht. Alles, was es tut, außer anzurufen execve()
oder _exit()
, hat ein großes Potenzial, die Eltern durcheinander zu bringen. Insbesondere exit()
ruft atexit()
Handler und andere „Finalizers“, zum Beispiel: es stdio Streams spült. Die Rückkehr von einem vfork()
Kind würde möglicherweise (dieselbe Einschränkung wie zuvor) den Stapel der Eltern durcheinander bringen.
fork
Syscall aufruft ?