fork () Systemaufruf und Speicherplatz des Prozesses

8

Ich zitiere: "Wenn ein Prozess einen neuen Prozess mit dem Aufruf von fork () erstellt, werden nur die gemeinsamen Speichersegmente zwischen dem übergeordneten Prozess und dem neu untergeordneten Prozess geteilt. Kopien des Stapels und des Heaps werden für das neu erstellte erstellt Prozess "von" Betriebssystemkonzepten "Lösungen von Silberschatz.

Aber als ich dieses Programm ausprobiert habe

%Vor%

Das Ergebnis ist wie folgt:

%Vor%

Sowohl Eltern als auch Kind, die dieselbe Adresse drucken, die sich im Heap befindet.

kann mir jemand den Widerspruch hier erklären. Bitte geben Sie klar an, was alle Dinge sind, die von Eltern und Kindern im Speicher geteilt werden.

    
gman 15.12.2014, 15:00
quelle

5 Antworten

17

Ich zitiere mich aus einem anderen Thread.

  •   

    Wenn ein fork () Systemaufruf ausgegeben wird, eine Kopie aller Seiten   entspricht dem übergeordneten Prozess erstellt wird, in ein separates geladen   Speicherort durch das Betriebssystem für den Kindprozess. Aber das ist nicht   in bestimmten Fällen benötigt. Betrachten Sie den Fall, wenn ein Kind einen ausführt   "exec" Systemaufruf oder beendet sehr bald nach dem fork (). Wenn das   child wird nur benötigt, um einen Befehl für den übergeordneten Prozess auszuführen,   Es ist nicht notwendig, die Seiten des übergeordneten Prozesses zu kopieren, da exec   ersetzt den Adressraum des Prozesses, der ihn aufgerufen hat   Befehl ausgeführt werden.

         

    In solchen Fällen wird eine Technik namens Copy-on-Write (COW) verwendet. Mit   Wenn eine Verzweigung auftritt, sind dies nicht die Seiten des übergeordneten Prozesses   für den Kindprozess kopiert. Stattdessen werden die Seiten zwischen geteilt   das Kind und der Elternprozess. Wann immer ein Prozess (Eltern oder Kind)   Ändert eine Seite, es wird eine separate Kopie dieser bestimmten Seite erstellt   für diesen Prozess (Eltern oder Kind), der die Änderung durchgeführt hat.   Dieser Prozess verwendet dann die neu kopierte Seite und nicht die   in allen zukünftigen Referenzen geteilt. Der andere Prozess (derjenige der   die freigegebene Seite nicht geändert hat) verwendet weiterhin die Originalkopie von   die Seite (die jetzt nicht mehr geteilt wird). Diese Technik wird aufgerufen   copy-on-write, da die Seite kopiert wird, wenn ein Prozess in sie schreibt.

  • Um zu verstehen, warum diese Programme den gleichen Speicherplatz zu verwenden scheinen (was nicht der Fall ist), möchte ich einen Teil des Buches "Betriebssysteme: Prinzipien und Praxis" zitieren.

      

    Die meisten modernen Prozessoren führen eine Ebene der Indirektion ein, genannt   virtuelle Adressen. Mit virtuellen Adressen, jedem Prozessspeicher   beginnt am "gleichen" Ort, z. B. Null.   Jeder Prozess denkt, dass er die gesamte Maschine für sich hat, obwohl   offensichtlich ist das in der Realität nicht der Fall.

    Also sind diese virtuellen Adressen Übersetzungen physikalischer Adressen und stellen nicht den gleichen physikalischen Speicherplatz dar. Um ein praktischeres Beispiel zu geben, können wir einen Test machen, wenn wir ein Programm, das die Richtung eines anzeigt, mehrfach kompilieren und ausführen statische Variable, wie dieses Programm.

    %Vor%

    Es wäre unmöglich, dieselbe Speicheradresse in zwei zu erhalten verschiedene Programme, wenn wir direkt mit dem physikalischen Speicher umgehen.

    Und die Ergebnisse, die man erhält, wenn man das Programm mehrmals ausführt, sind ...

    
OiciTrap 15.12.2014, 15:18
quelle
9

Ja, beide Prozesse verwenden dieselbe Adresse für diese Variable, aber diese Adressen werden von verschiedenen Prozessen verwendet und sind daher nicht in der gleichen virtueller Adressraum .

Dies bedeutet, dass die Adressen identisch sind, aber nicht auf denselben physischen Speicher zeigen. Sie sollten mehr über den virtuellen Speicher lesen, um dies zu verstehen.

    
ElderBug 15.12.2014 15:09
quelle
5

Sie führen Ihr Programm wahrscheinlich auf einem Betriebssystem mit virtuellem Speicher aus. Nach dem Aufruf von fork() haben Eltern und Kind getrennte Adressräume, sodass die Adresse 0x1370010 nicht auf dieselbe Stelle zeigt. Wenn ein Prozess an *x schrieb, würde der andere Prozess die Änderung nicht sehen. (In der Tat können diese die gleiche Seite des Speichers oder sogar derselbe Block in einer Swap-Datei sein, bis sie geändert wird, aber das Betriebssystem stellt sicher, dass die Seite kopiert wird, sobald entweder das Elternteil oder das Kind darauf schreibt, Soweit das Programm feststellen kann, dass es sich um eine eigene Kopie handelt.)

    
david 15.12.2014 15:10
quelle
4

Die Adresse ist die gleiche, aber der Adressraum nicht. Jeder Prozess hat seinen eigenen Adressraum, also ist die 0x1370010 des Elternteils nicht die gleiche wie die 0x1370010 des Kindes.

    
Sergej Christoforov 15.12.2014 15:09
quelle
3

Wenn der Kernel fork() s der Prozess ist, erbt die kopierte Speicherinformation die gleiche Adressinformation, da der Heap tatsächlich unverändert kopiert wird. Wenn Adressen anders wären, wie würden Sie Zeiger innerhalb von benutzerdefinierten Strukturen aktualisieren? Der Kernel weiß nichts über diese Information, daher würden diese Zeiger ungültig gemacht. Daher kann sich die physische -Adresse ändern (und wird sich sogar während der Laufzeit Ihrer ausführbaren Datei sogar ohne fork() ing ändern, aber die logische -Adresse bleibt gleich.

    
inetknght 15.12.2014 15:10
quelle

Tags und Links