Was ist der Unterschied zwischen MAP_SHARED und MAP_PRIVATE in der mmap-Funktion?

Lesezeit: 3 Minuten

Benutzeravatar von ntl0ve
ntl0ve

Herumspielen mit mmap Zum Spaß habe ich folgenden Code:

(.. snip ..)
fd = open("/home/me/straight_a.txt", O_RDONLY);
if (fd == -1) {
    perror("open");
    exit(1);
}

m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);

if (m == MAP_FAILED) {
    perror("mmap");
    exit(1);
}

printf("m is %p\n", m);

printf("*m = %c\n", *m);
printf("*(m+1) = %c\n", *(m+1));
(.. snip ..)

Dies funktioniert wie erwartet. Aber bevor ich dazu kam, versuchte ich…

m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);

… und mmap hat einen Fehler ausgegeben mit:

mmap: Permission denied

Was ist im Allgemeinen der Unterschied zwischen den beiden Flags (Manpage ist zu diesem Thema nicht zu großzügig)? Welche Art von Erlaubnis (und wo) fehlt mir?

BEARBEITEN

Wie es normalerweise passiert … habe es teilweise herausgefunden.

Es stellt sich heraus open brauchte ein O_RDWR Flagge.

Gehe ich also richtig davon aus, dass:

  • MAP_PRIVATE – Änderungen werden nur im Arbeitsspeicher vorgenommen, nicht auf der Festplatte gespeichert?
  • MAP_SHARED – Änderungen würden auf der Festplatte gespeichert …

… aber ich speichere nirgendwo etwas auf der Festplatte, dachte ich? Nur mit Speicher arbeiten.

  • , O_RDONLY); Die Datei ist schreibgeschützt. Es kann nicht als Sicherungsspeicher für a verwendet werden PROT_READ|PROT_WRITE mmap()ed-Bereich, da er nicht beschreibbar ist. Das MAP_PRIVATE Mapping muss nicht in die Datei schreiben (die Datei wird nur zum Lesen verwendet, vermutlich von COW) Hinweis: Ich würde nicht erwarten, dass die Tilde-Erweiterung für open(2) funktioniert. Es würde mich wundern, wenn es funktioniert.

    – Wildpässer

    1. März 2012 um 16:12 Uhr


  • Richtig, es war nur ein schneller Weg, um das eigentliche Basisverzeichnis da rauszuholen, habe nicht einmal darüber nachgedacht. Danke, der Korrektheit halber korrigiert.

    – ntl0ve

    1. März 2012 um 19:42 Uhr

Sie haben die Datei im schreibgeschützten Modus geöffnet. Dann haben Sie versucht, einen Teil davon im Lese-/Schreibmodus mit gesetztem MAP_SHARED zu mmapping. In diesem Zusammenhang impliziert MAP_SHARED, dass, wenn Sie in die mmap-Region schreiben, Ihre Änderungen in die zugeordnete Datei selbst zurückgeschrieben werden. Dies ist nicht möglich, da Sie die Datei im schreibgeschützten Modus geöffnet haben.

MAP_PRIVATE funktioniert, weil Schreibvorgänge in die mmap-Region nicht in die Originaldatei zurückgeschrieben werden. Wenn Sie in die Region schreiben, werden die Seiten, in die geschrieben wurde, in eine andere Speicherregion kopiert, möglicherweise unterstützt durch Auslagerungsspeicher.

Schreibvorgänge in ein MAP_SHARED-Segment werden in die zugrunde liegende Datei übertragen. Sie haben die Datei mit O_RDONLY geöffnet, was mit dem PROT_WRITE-Flag in Konflikt steht, wodurch verhindert wird, dass MAP_SHARED in die Datei zurückschreiben kann.

MAP_PRIVATE führt keine Schreibvorgänge in die zugrunde liegende Datei zurück, sodass die Tatsache, dass Sie die Datei O_RDONLY geöffnet haben, kein Problem darstellt.

  • Wann werden meine Änderungen im Arbeitsspeicher auf die Festplatte übertragen? Muss ich anrufen oder geht das automatisch? Wenn ja, Pufferung?

    – ntl0ve

    1. März 2012 um 16:17 Uhr


  • Kurze Antwort: Sie wissen es nicht. Alles zwischen jetzt und der Ewigkeit. munmap() kann je nach Mondphase die Festplattenpuffer leeren.

    – Wildpässer

    1. März 2012 um 16:20 Uhr

  • Habe es. Auch gefunden msync, das verspricht, ein Flush/Sync zu erzwingen. Danke.

    – ntl0ve

    1. März 2012 um 16:23 Uhr

  • @wildplasser Meiner Erfahrung nach leert munmap() niemals Puffer. Daher können Sie mmap/munmap verwenden, um Adressraumfenster zu implementieren, wenn der physische Speicher den Adressraum des virtuellen Speichers überschreitet.

    – Karunsky

    1. März 2012 um 18:20 Uhr

  • Das ist richtig. Es lässt sie einfach in der Schreibwarteschlange (wenn sie schmutzig sind). MAP_SYNC bewirkt, dass munmap() blockiert, bis sie tatsächlich geschrieben werden (genau wie msync()). Das ist die Phase des Mondes Teil der Geschichte.

    – Wildpässer

    1. März 2012 um 18:50 Uhr

1437350cookie-checkWas ist der Unterschied zwischen MAP_SHARED und MAP_PRIVATE in der mmap-Funktion?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy