mmmapa - mmap
W computing , mmap(2)
jest POSIX zgodny ze Unix wywołanie systemowe , które odwzorowuje plików lub urządzeń w pamięci. Jest to metoda operacji wejścia/wyjścia plików mapowanych w pamięci . Implementuje stronicowanie na żądanie, ponieważ zawartość pliku nie jest odczytywana bezpośrednio z dysku i początkowo w ogóle nie korzysta z fizycznej pamięci RAM. Rzeczywiste odczyty z dysku są wykonywane w sposób " leniwy ", po uzyskaniu dostępu do określonej lokalizacji. Gdy pamięć nie jest już potrzebna, ważne jest, aby munmap(2)
wskaźniki do niej. Informacje o ochronie można zarządzać za pomocą mprotect(2)
, a specjalne traktowanie można wymusić za pomocą madvise(2)
.
W systemie Linux , macOS i BSD , mmap
można tworzyć kilka typów mapowań. Inne systemy operacyjne mogą obsługiwać tylko ich część; na przykład współdzielone mapowania mogą nie być praktyczne w systemie operacyjnym bez globalnej pamięci podręcznej VFS lub we/wy.
Historia
Oryginalny projekt plików mapowanych w pamięci pochodził z systemu operacyjnego TOPS-20 . mmap
i powiązane wywołania systemowe zostały zaprojektowane jako część wersji Unix Berkeley Software Distribution (BSD). Ich API zostało już opisane w Podręczniku Systemu 4.2BSD, mimo że nie zostało ani zaimplementowane w tym wydaniu, ani w 4.3BSD. Firma Sun Microsystems zaimplementowała ten sam interfejs API w swoim systemie operacyjnym SunOS . Deweloperzy BSD z UC Berkeley poprosili firmę Sun o przekazanie jej implementacji, ale rozmowy te nigdy nie doprowadziły do przekazania kodu; 4.3BSD-Reno został dostarczony z implementacją opartą na systemie pamięci wirtualnej Macha .
Poparte plikami i anonimowe
Mapowanie oparte na plikach mapuje obszar pamięci wirtualnej procesu na pliki; tj. czytanie tych obszarów pamięci powoduje odczytanie pliku. Jest to domyślny typ mapowania.
Mapowanie anonimowe mapuje obszar pamięci wirtualnej procesu, który nie jest poparty żadnym plikiem. Zawartość jest inicjowana na zero. Pod tym względem mapowanie anonimowe jest podobne do malloc
i jest używane w niektórych malloc(3)
implementacjach dla określonych alokacji. Jednak mapowania anonimowe nie są częścią standardu POSIX, chociaż są implementowane przez prawie wszystkie systemy operacyjne przez flagi MAP_ANONYMOUS
i MAP_ANON
.
Widoczność pamięci
Jeśli mapowanie jest współdzielone ( MAP_SHARED
flaga jest ustawiona), to jest zachowywane przez wywołanie systemowe fork(2) . Oznacza to, że zapisy w zmapowanym obszarze w jednym procesie są natychmiast widoczne we wszystkich powiązanych procesach (rodzic, dziecko lub rodzeństwie). Jeśli mapowanie jest współdzielone i wspierane przez plik (nie MAP_ANONYMOUS
), na nośniku pliku bazowego jest zagwarantowane, że zostanie zapisany dopiero po wykonaniu msync(2).
Jeśli mapowanie jest prywatne ( MAP_PRIVATE
flaga jest ustawiona), zmiany nie będą widoczne dla innych procesów ani zapisane w pliku.
Proces odczytujący lub zapisujący plik bazowy nie zawsze będzie widział te same dane, co proces, który zmapował plik, ponieważ segment pliku jest kopiowany do pamięci RAM i okresowo opróżniany na dysk. Synchronizację można wymusić msync
wywołaniem systemowym.
Pliki mmap(2)ing mogą znacznie zmniejszyć obciążenie pamięci dla aplikacji uzyskujących dostęp do tego samego pliku; mogą dzielić obszar pamięci, który obejmuje plik, zamiast ładować plik dla każdej aplikacji, która chce do niego uzyskać dostęp. Oznacza to, że mmap(2) jest czasami używany do komunikacji międzyprocesowej (IPC). W nowoczesnych systemach operacyjnych , mmap (2) jest zwykle korzystne z System V IPC Shared Memory obiektu.
Główną różnicą między pamięcią współdzieloną Systemu V (shmem) a mapowaniem we/wy (mmap) jest to, że pamięć współdzielona Systemu V jest trwała: jeśli nie zostanie wyraźnie usunięta przez proces, jest przechowywana w pamięci i pozostaje dostępna do momentu zamknięcia systemu . Pamięć mmap nie jest trwała między wykonaniami aplikacji (chyba że jest wspierana przez plik).
Przykład użycia w ramach języka programowania C
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* This example shows how an mmap of /dev/zero is equivalent to
using anonymous memory (MAP_ANON) not connected to any file.
N.B. MAP_ANONYMOUS or MAP_ANON are supported by most UNIX
versions, removing the original purpose of /dev/zero.
*/
/* Does not work on OS X or macOS, where you can't mmap over /dev/zero */
int main(void)
{
const char str1[] = "string 1";
const char str2[] = "string 2";
pid_t parpid = getpid(), childpid;
int fd = -1;
char *anon, *zero;
if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
err(1, "open");
anon = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
zero = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (anon == MAP_FAILED || zero == MAP_FAILED)
errx(1, "either mmap");
strcpy(anon, str1);
strcpy(zero, str1);
printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
switch ((childpid = fork())) {
case -1:
err(1, "fork");
/* NOTREACHED */
case 0:
childpid = getpid();
printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
sleep(3);
printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
munmap(anon, 4096);
munmap(zero, 4096);
close(fd);
return EXIT_SUCCESS;
}
sleep(2);
strcpy(anon, str2);
strcpy(zero, str2);
printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
munmap(anon, 4096);
munmap(zero, 4096);
close(fd);
return EXIT_SUCCESS;
}
przykładowe dane wyjściowe:
PID 22475: anonymous string 1, zero-backed string 1 PID 22476: anonymous string 1, zero-backed string 1 PID 22475: anonymous string 2, zero-backed string 2 PID 22476: anonymous string 2, zero-backed string 2
Zobacz też
- Pamięć wirtualna, gdy jest więcej przestrzeni adresowej niż pamięć fizyczna
- Stronicowanie do implementacji pamięci wirtualnej
- Pamięć podręczna stron dla mechanizmu buforowania dysku używanego przez mmap
- Stronicowanie popytu dla schematu realizowanego przez mmap
Bibliografia
Dalsza lektura
- Opis ze standardu POSIX
- Różnice:
- Okna
- Funkcja Win32 MapViewOfFile jest poniekąd odpowiednikiem Mmap.
- Więcej przykładowego kodu źródłowego:
- SharedHashFile , tablica skrótów pamięci współdzielonej typu open source zaimplementowana za pomocą mmap().