En informática , mmap(2)
es una llamada al sistema Unix compatible con POSIX que asigna archivos o dispositivos a la memoria. Es un método de E / S de archivos mapeados en memoria . Implementa la paginación por demanda porque el contenido del archivo no se lee directamente desde el disco e inicialmente no usa RAM física en absoluto. Las lecturas reales del disco se realizan de manera " perezosa ", después de acceder a una ubicación específica. Una vez que la memoria ya no es necesaria, es importante que los apuntes a ella. La información de protección se puede administrar usando y se puede aplicar un tratamiento especial usando . munmap(2)
mprotect(2)
madvise(2)
En Linux , macOS y BSD , se mmap
pueden crear varios tipos de asignaciones. Es posible que otros sistemas operativos solo admitan un subconjunto de estos; por ejemplo, las asignaciones compartidas pueden no ser prácticas en un sistema operativo sin un VFS global o caché de E / S.
Historia
El diseño original de archivos mapeados en memoria provino del sistema operativo TOPS-20 . mmap
y las llamadas a sistemas asociados se diseñaron como parte de la versión Berkeley Software Distribution (BSD) de Unix. Su API ya se describió en el Manual del sistema 4.2BSD, aunque no se implementó en esa versión ni en 4.3BSD. [1] Sun Microsystems había implementado esta misma API, sin embargo, en su sistema operativo SunOS . Los desarrolladores de BSD en UC Berkeley solicitaron a Sun que donara su implementación, pero estas conversaciones nunca llevaron a ninguna transferencia de código; 4.3BSD-Reno se envió en su lugar con una implementación basada en el sistema de memoria virtual de Mach . [2]
Anónimo y respaldado por archivos
El mapeo respaldado por archivos asigna un área de la memoria virtual del proceso a los archivos; es decir, leer esas áreas de la memoria hace que se lea el archivo. Es el tipo de mapeo predeterminado.
El mapeo anónimo mapea un área de la memoria virtual del proceso que no está respaldada por ningún archivo. El contenido se inicializa a cero. [3] A este respecto, un mapeo anónimo es similar malloc
y se utiliza en algunas malloc(3)
implementaciones para determinadas asignaciones. Sin embargo, las asignaciones anónimas no son parte del estándar POSIX, aunque implementadas por casi todos los sistemas operativos mediante las banderas MAP_ANONYMOUS
y MAP_ANON
.
Visibilidad de la memoria
Si el mapeo es compartido (la MAP_SHARED
bandera está establecida), entonces se conserva a través de una llamada al sistema fork (2) . Esto significa que las escrituras en un área mapeada en un proceso son inmediatamente visibles en todos los procesos relacionados (padre, hijo o hermano). Si el mapeo es compartido y respaldado por un archivo (no MAP_ANONYMOUS
), el medio de archivo subyacente solo se garantiza que se escribirá después de que sea msync (2) 'ed.
Si el mapeo es privado (la MAP_PRIVATE
bandera está establecida), los cambios no serán vistos por otros procesos ni escritos en el archivo.
Un proceso que lee o escribe en el archivo subyacente no siempre verá los mismos datos que un proceso que ha asignado el archivo, ya que el segmento del archivo se copia en la RAM y se descarga periódicamente en el disco. La sincronización se puede forzar con la msync
llamada al sistema.
Los archivos mmap (2) pueden reducir significativamente la sobrecarga de memoria para las aplicaciones que acceden al mismo archivo; pueden compartir el área de memoria que abarca el archivo, en lugar de cargar el archivo para cada aplicación que desee acceder a él. Esto significa que mmap (2) a veces se usa para la comunicación entre procesos (IPC). En los sistemas operativos modernos , normalmente se prefiere mmap (2) a la función de memoria compartida System V IPC .
La principal diferencia entre la memoria compartida System V (shmem) y la E / S mapeada en memoria (mmap) es que la memoria compartida SystemV es persistente: a menos que un proceso la elimine explícitamente, se mantiene en la memoria y permanece disponible hasta que se apaga el sistema. La memoria mmap no es persistente entre ejecuciones de aplicaciones (a menos que esté respaldada por un archivo).
Ejemplo de uso bajo el lenguaje de programación C
#include #include #include #include #include #include #include #include / * Este ejemplo muestra cómo un mmap de / dev / zero es equivalente a usar memoria anónima (MAP_ANON) no conectada a ningún archivo. NB MAP_ANONYMOUS o MAP_ANON son compatibles con la mayoría de las versiones de UNIX , eliminando el propósito original de / dev / zero. * / / * No funciona en OS X o macOS, donde no puede mmap sobre / dev / zero * / int main ( void ) { const char str1 [] = "string 1" ; const char str2 [] = "cadena 2" ; pid_t parpid = getpid (), childpid ; int fd = -1 ; char * anon , * cero ; 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 ); cero = ( char * ) mmap ( NULL , 4096 , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 ); if ( anon == MAP_FAILED || cero == MAP_FAILED ) errx ( 1 , "cualquier mmap" ); strcpy ( anon , str1 ); strcpy ( cero , str1 ); printf ( "PID% d: \ t % s anónimo,% s con respaldo cero \ n " , parpid , anon , cero ); switch (( childpid = fork ())) { case -1 : err ( 1 , "fork" ); / * NO ALCANZADO * / caso 0 : childpid = getpid (); printf ( "PID% d: \ t % s anónimo,% s con respaldo cero \ n " , childpid , anon , cero ); dormir ( 3 ); printf ( "PID% d: \ t % s anónimo,% s con respaldo cero \ n " , childpid , anon , cero ); munmap ( anon , 4096 ); munmap ( cero , 4096 ); cerrar ( fd ); return EXIT_SUCCESS ; } dormir ( 2 ); strcpy ( anon , str2 ); strcpy ( cero , str2 ); printf ( "PID% d: \ t % s anónimo,% s con respaldo cero \ n " , parpid , anon , cero ); munmap ( anon , 4096 ); munmap ( cero , 4096 ); cerrar ( fd ); return EXIT_SUCCESS ; }
salida de muestra:
PID 22475: cadena anónima 1, cadena 1 sin respaldoPID 22476: cadena anónima 1, cadena 1 sin respaldoPID 22475: cadena anónima 2, cadena 2 sin respaldoPID 22476: cadena anónima 2, cadena 2 con respaldo cero
Ver también
- Memoria virtual para cuando hay más espacio de direcciones que la memoria física
- Paginación para la implementación de memoria virtual
- Caché de página para un mecanismo de almacenamiento en caché de disco utilizado por mmap
- Solicitar paginación para un esquema implementado por mmap
Referencias
- ^ William Joy ; Eric Cooper; Robert Fabry ; Samuel Leffler ; Kirk McKusick ; David Mosher (1983). 4.2 Manual del sistema BSD (PDF) (Informe). Grupo de Investigación de Sistemas Computacionales , Universidad de California, Berkeley .
- ^ McKusick, Marshall Kirk (1999). "Veinte años de Berkeley Unix: de propiedad de AT&T a libremente redistribuible". Fuentes abiertas: voces de la revolución de las fuentes abiertas . O'Reilly.
- ^ "mmap (2) - Página de manual de Linux" .
Otras lecturas
- Descripción del estándar POSIX
- Diferencias:
- DragonFly BSD
- FreeBSD
- NetBSD
- OpenBSD
- Ilumina
- Mac OS X
- Solaris
- HP-UX
- QNX
- Ventanas
- La función MapViewOfFile win32 es algo equivalente a mmap.
- Más código fuente de ejemplo:
- SharedHashFile , una tabla hash de memoria compartida de código abierto implementada mediante mmap ().