Laut Wikipedia (was falsch sein könnte)
Bei einem Systemaufruf von fork () wird eine Kopie aller Seiten erstellt, die dem übergeordneten Prozess entsprechen, und vom Betriebssystem für den untergeordneten Prozess in einen separaten Speicherort geladen. In bestimmten Fällen ist dies jedoch nicht erforderlich. Betrachten Sie den Fall, dass ein Kind einen "
exec
" Systemaufruf ausführt (mit dem eine ausführbare Datei in einem C - Programm ausgeführt wird) oder sehr bald nach dem beendet wirdfork()
. Wenn das untergeordnete Element nur zum Ausführen eines Befehls für den übergeordneten Prozess benötigt wird, müssen die Seiten des übergeordneten Prozesses nicht kopiert werden, daexec
der Adressraum des aufgerufenen Prozesses durch den auszuführenden Befehl ersetzt wird.In solchen Fällen wird eine Technik verwendet, die als Copy-on-Write (COW) bezeichnet wird. Bei dieser Technik werden beim Verzweigen die Seiten des übergeordneten Prozesses nicht für den untergeordneten Prozess kopiert. Stattdessen werden die Seiten zwischen dem untergeordneten und dem übergeordneten Prozess geteilt. Wenn ein Prozess (übergeordnet oder untergeordnet) eine Seite ändert, wird nur eine separate Kopie dieser bestimmten Seite für den Prozess (übergeordnet oder untergeordnet) erstellt, der die Änderung durchgeführt hat. Bei diesem Vorgang wird in allen zukünftigen Verweisen die neu kopierte Seite anstelle der freigegebenen Seite verwendet. Der andere Prozess (der die freigegebene Seite nicht geändert hat) verwendet weiterhin die Originalkopie der Seite (die jetzt nicht mehr freigegeben ist). Diese Technik wird als Copy-on-Write bezeichnet, da die Seite kopiert wird, wenn ein Prozess darauf schreibt.
Es scheint, dass, wenn einer der Prozesse versucht, auf die Seite zu schreiben, eine neue Kopie der Seite zugewiesen und dem Prozess zugewiesen wird, der den Seitenfehler erzeugt hat. Die Originalseite wird anschließend als beschreibbar markiert.
Meine Frage ist: Was passiert, wenn die fork()
mehrmals aufgerufen wird, bevor einer der Prozesse versucht, auf eine freigegebene Seite zu schreiben?
pmap -XX PID
oder überprüfencat /proc/PID/smap
.Antworten:
Es passiert nichts Besonderes. Alle Prozesse teilen sich die gleichen Seiten und jeder erhält eine eigene private Kopie, wenn er eine Seite ändern möchte.
quelle
Das Verhalten von fork () hängt davon ab, ob das * nix-System eine MMU hat oder nicht. Auf einem Nicht-MMU-System (wie frühen PDP-11-Systemen) hat der Systemaufruf fork () den gesamten Arbeitsspeicher der Eltern für jedes Kind kopiert. Auf einem MMU-basierten * nix-System markiert der Kernel alle nicht gestapelten Seiten als R / O und teilt sie zwischen übergeordneten und untergeordneten Seiten. Wenn dann einer der beiden Prozesse auf eine Seite schreibt, fängt die MMU den Versuch ab, der Kernel weist dann eine beschreibbare Seite zu und aktualisiert die MMU-Seitentabellen so, dass sie auf die jetzt beschreibbare Seite verweisen. Dieses Verhalten beim Kopieren beim Schreiben sorgt für eine Beschleunigung, da anfangs nur ein privater Stapel für jeden untergeordneten Prozess zugewiesen und geklont werden muss.
Wenn Sie zwischen den Aufrufen von fork () übergeordneten Code ausführen, unterscheiden sich die resultierenden untergeordneten Prozesse von den Seiten, die vom übergeordneten Code geändert wurden. Wenn das übergeordnete Element hingegen einfach mehrere fork () - Aufrufe ausgibt, z. B. in einer Schleife, sind die untergeordneten Prozesse nahezu identisch. Wenn eine lokale Schleifenvariable verwendet wird, ist dies innerhalb des Stapels jedes Kindes unterschiedlich.
quelle
Wenn das System eine Verzweigung durchführt (dies kann von der Implementierung abhängen), werden die Seiten normalerweise auch als schreibgeschützt und der übergeordnete Prozess als Master dieser Seiten gekennzeichnet.
Beim Versuch, auf diese Seiten zu schreiben, tritt ein Seitenfehler auf, und das Betriebssystem übernimmt das Kopieren der gesamten Liste der Seiten oder nur der geänderten Seiten (wiederum abhängig von der Implementierung), sodass für den Schreibvorgang eine beschreibbare Kopie erstellt wird.
Wenn es mehrere Prozesse gibt, die aus demselben Prozess hervorgehen, und der "Master" -Prozess in seinen Speicher schreibt, werden für die anderen Prozesse die entsprechenden Seiten kopiert.
quelle