[Ich werde einen Teil meiner Antwort von hier aus wiederholen .]
Warum nicht einfach einen Befehl haben, der einen neuen Prozess von Grund auf neu erstellt? Ist es nicht absurd und ineffizient, eine zu kopieren, die nur sofort ersetzt wird?
In der Tat wäre das wahrscheinlich aus ein paar Gründen nicht so effizient:
Die von erzeugte "Kopie" fork()
ist eine Art Abstraktion, da der Kernel ein Copy-on-Write- System verwendet . alles, was wirklich erstellt werden muss, ist eine virtuelle Speicherkarte. Wenn die Kopie dann sofort aufgerufen wird exec()
, müssen die meisten Daten, die kopiert worden wären, wenn sie durch die Aktivität des Prozesses geändert worden wären, niemals tatsächlich kopiert / erstellt werden, da der Prozess nichts tut, was seine Verwendung erfordert.
Verschiedene wichtige Aspekte des untergeordneten Prozesses (z. B. seine Umgebung) müssen nicht einzeln dupliziert oder basierend auf einer komplexen Kontextanalyse usw. festgelegt werden. Es wird lediglich davon ausgegangen, dass sie mit denen des aufrufenden Prozesses identisch sind Dies ist das ziemlich intuitive System, mit dem wir vertraut sind.
Um # 1 ein wenig weiter zu erläutern, wird der Speicher, auf den "kopiert", aber später nie zugegriffen wird, zumindest in den meisten Fällen nie wirklich kopiert. Eine Ausnahme in diesem Kontext kann sein, wenn Sie einen Prozess gegabelt haben und dann den übergeordneten Prozess beendet haben, bevor sich das untergeordnete Element durch ersetzt hat exec()
. Ich sage möglicherweise, weil ein Großteil des übergeordneten Elements zwischengespeichert werden könnte, wenn genügend freier Speicher vorhanden ist, und ich bin nicht sicher, in welchem Umfang dies ausgenutzt würde (was von der Betriebssystemimplementierung abhängen würde).
Natürlich tut das nicht auf der Oberfläche um eine Kopie mit mehr effizienter als die Verwendung ein unbeschriebenes Blatt - mit Ausnahme von „der unbeschriebenes Blatt“ nichts nicht wörtlich ist, und die Zuweisung beinhalten muss. Das System könnte eine generische leere / neue Prozessvorlage haben, die auf die gleiche Weise kopiert wird, 1 die dann jedoch nichts im Vergleich zur Kopie beim Schreiben wirklich rettet. Die Nummer 1 zeigt also nur, dass die Verwendung eines "neuen" leeren Prozesses nicht effizienter wäre.
Punkt 2 erklärt, warum die Verwendung der Gabel wahrscheinlich effizienter ist. Die Umgebung eines Kindes wird von seiner Eltern geerbt, auch wenn es sich um eine völlig andere ausführbare Datei handelt. Wenn beispielsweise der übergeordnete Prozess eine Shell und der untergeordnete ein Webbrowser ist, $HOME
ist dies für beide immer noch derselbe. Da jedoch beide Prozesse dies später ändern könnten, müssen dies zwei separate Kopien sein. Derjenige im Kind wird vom Original produziert fork()
.
1. Eine Strategie, die wörtlich nicht viel Sinn macht, aber ich möchte betonen, dass das Erstellen eines Prozesses mehr beinhaltet als das Kopieren des Images vom Datenträger in den Speicher.