copy on write?

Da war mal was…

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

copy on write?
Das ist jetzt nicht speziell klausurbezogen, aber wo es mir grade wieder einfällt: Uns wurde doch in der Vorlesung mal was erzählt, dass z.B. bei einem fork() oder so erstmal die Segmente von beiden Prozessen gemeinsam benutzt werden, und nur bei Schreibzugriffen die Änderungen an eine neue Speicherstelle übertragen werden. Dadurch geht das Erzeugen des ‘neuen’ Speicherbereichs viel schneller, und wenn keiner was schreiben will, ist ein Kopieren nicht nötig. Irgendwas mit “copy on write” oder so ähnlich wurde das genannt. Weiß da jemand genaueres zu? Werden dann bei Bedarf einzelne Adressen geändert, oder ganze Seiten oder Segmente kopiert? Wie wird das erkannt und geregelt? Details… Input… :smiley:


na ja - immerhin hab’ ich das in der Vorl. erzaehlt :slight_smile:

beim forkwird konzeptionell der ganze Speicher fuer den Sohn kopiert.
bei copy on write passiert das nicht sondern:

  1. dem Vater wird das Schreibrecht auf die Pages entzogen (werden im
    Pagedeskritor als read-only markiert)
  2. in der SKT des Sohnes wird in den Pagedeskriptoren die gleiche
    phys. Adresse wir beim vater eingetragen - recht ebenfalls read-only
  3. wenn einer von beiden schreibend zugreift gibt’s einen page-fault
    wegen der Zugriffsrechtverletzung. Das BS kopiert die Seite, gibt einem
    die Kopie, laesst dem anderen das Original und traegt bei beiden wieder
    read/write-recht ein - und laesst den Verursacher des page-faults
    weiterlaufen.
  4. wenn einer der beiden Prozesse (meistens der Sohn) wegen
    exec oder exit seinen Speicher aufgibt, erhaelt der andere wieder
    read/write-recht.

Nachdem 95% aller Prozesse nach dem fork sowieso sofort ein
exec machen, spart man sich auf diese Weise das Kopieren und
anschliessende Wegwerfen von Speicher.

Statt mit einzelenen Seiten funktioniert das natuerlich auch mit ganzen
Segmenten (da ist’s einerseits einfacher, weil man nur die Segmente
read-only setzen muss, das sind nicht so viele. Andererseits wird’s teurer
weil man bei einem Schriebzugriff dann das jeweilige ganze Segment
kopieren muss. Fuer den typischen fork-exec-Fall ist das aber
unproblematisch weil der Sohn ja vor dem exec meist
eh’ keine Daten veraendert. Tut er’s doch dann bringt’s mit Segmenten
nicht mehr viel. Im Fall von Pages ist copy on write dann immer noch
ganz gut, weil vermutlich hoechstens 1-2 Seiten betroffen sind.


wenn wir schon bei nicht so richtig prüfungsrelevantem sind: warum gibt es diesen fork-mechanismus denn überhaupt? ich meine, dass ist ja sehr cool, mit kindern und so, aber ginge das nicht auch über eine neu-prozess-erzeugung?
ich nehme an, es gibt mal wieder historische gründe?


Süßwaren-Affen … typisch :smiley:

Am Dienstag ist Ordner ins Regal schieben angesagt! Mindestens 5 mal!

jo


Also ich find ja diese Funktion sehr cool: [url=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createremotethread.asp]CreateRemoteThread[/url] (Win32 Platform SDK). Damit lass ich meinen Thread mal eben in nem anderen Prozess laufen... Wenn ich mich nicht zu sehr täusche, hab ich diese Funktion sogar mal im guten alten BO2K-Quelltext gesehen! :rolleyes:

Ich les das mit den copy-on-write pages grade in der fork manpage… sowas… Und wenn der child process dann gleich ein execve macht, kann man auch die vfork-Funktion verwenden, aus Zeitgründen. Nett. In der vfork manpage steht übrigens auch noch ein klein wenig unverständliche Linux/BSD history dazu…


wer um alles in der Welt hat denn gesagt dass das nicht
pruefungsrelevant ist???

man wollte die Betriebssystemschnittstelle auf ein paar minimale Abstraktionen
reduzieren. fork ist ja genau die „neu-prozess-erzeugung“, exec ist
das Ausfuehren eines Programms in einem Prozess.
Das Problem war dann halt nur, dass das zwar konzeptionell sehr
sauber ist, aber ziemlich ineffizient.
Drum zuerst sowas wie vfork (da erbt der Sohn einfach den
Speicher des Vaters und der Veter wird blockiert bis der Sohn exec oder exit
macht - allerdings mit dem nebeneffekt, dass der Sohn vor dem exec noch
Daten des Vaters veraendern kann, also nicht ganz sauber) und dann mit
den seitenadressierten UNIX-Systemen das copy-on-write.