Los archivos asignados en memoria se pueden usar para reemplazar el acceso de lectura / escritura o para admitir el uso compartido simultáneo. Cuando los usa para un mecanismo, obtiene el otro también.
En lugar de buscar, escribir y leer en un archivo, lo asigna a la memoria y simplemente accede a los bits donde espera que estén.
Esto puede ser muy útil y, dependiendo de la interfaz de memoria virtual, puede mejorar el rendimiento. La mejora del rendimiento puede ocurrir porque el sistema operativo ahora puede administrar esta "E / S de archivo" anterior junto con todos sus otros accesos de memoria programáticos, y puede (en teoría) aprovechar los algoritmos de paginación y demás que ya está usando para admitir memoria virtual para el resto de su programa. Sin embargo, depende de la calidad de su sistema de memoria virtual subyacente. Anécdotas He escuchado decir que los sistemas de memoria virtual Solaris y * BSD pueden mostrar mejores mejoras de rendimiento que el sistema VM de Linux, pero no tengo datos empíricos para respaldar esto. YMMV.
La simultaneidad entra en escena cuando se considera la posibilidad de que múltiples procesos utilicen el mismo "archivo" a través de la memoria asignada. En el modelo de lectura / escritura, si dos procesos escribieron en la misma área del archivo, podría estar bastante seguro de que uno de los datos del proceso llegaría al archivo, sobrescribiendo los datos del otro proceso. Obtendría uno u otro, pero no una mezcla extraña. Debo admitir que no estoy seguro de si este es un comportamiento exigido por algún estándar, pero es algo en lo que puede confiar. (¡En realidad es una buena pregunta de seguimiento!)
En el mundo cartografiado, por el contrario, imagine dos procesos que "escriben". Lo hacen haciendo "almacenes de memoria", lo que da como resultado que el O / S pague los datos en el disco, eventualmente. Pero mientras tanto, se puede esperar que ocurran escrituras superpuestas.
He aquí un ejemplo. Digamos que tengo dos procesos que escriben 8 bytes en el desplazamiento 1024. El proceso 1 está escribiendo '11111111' y el proceso 2 está escribiendo '22222222'. Si usan E / S de archivo, entonces puede imaginarse, en el fondo del O / S, hay un búfer lleno de 1 y un búfer lleno de 2, ambos dirigidos al mismo lugar en el disco. Uno de ellos va a llegar primero y el otro un segundo. En este caso, gana el segundo. Sin embargo , si estoy usando el enfoque de archivo mapeado en memoria, el proceso 1 irá a un almacenamiento de memoria de 4 bytes, seguido de otro almacenamiento de memoria de 4 bytes (supongamos que ese no es el tamaño máximo de almacenamiento de memoria). El proceso 2 hará lo mismo. Según cuándo se ejecutan los procesos, puede esperar ver cualquiera de los siguientes:
11111111
22222222
11112222
22221111
La solución a esto es utilizar la exclusión mutua explícita, lo que probablemente sea una buena idea en cualquier caso. De todos modos, confiaba en el SO para hacer "lo correcto" en el caso de E / S de archivo de lectura / escritura.
La primitiva de exclusión mutua de clasificación es el mutex. Para archivos mapeados en memoria, le sugiero que busque un mutex mapeado en memoria, disponible usando (por ejemplo) pthread_mutex_init ().
Edite con un error: cuando está utilizando archivos mapeados, existe la tentación de incrustar punteros a los datos en el archivo, en el propio archivo (piense en la lista vinculada almacenada en el archivo mapeado). No desea hacer eso, ya que el archivo puede estar mapeado en diferentes direcciones absolutas en diferentes momentos o en diferentes procesos. En su lugar, utilice compensaciones dentro del archivo mapeado.