Skip to content

Instantly share code, notes, and snippets.

@ojgarciab
Last active February 15, 2018 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ojgarciab/b7cf58c74fec203c390fd096fe2ec277 to your computer and use it in GitHub Desktop.
Save ojgarciab/b7cf58c74fec203c390fd096fe2ec277 to your computer and use it in GitHub Desktop.

Ejemplo de uso de mmap en C

Generar ejecutable con:

cmake . && make

Probar el funcionamiento:

$ ./ejemplo /tmp/ejemplo
Datos iniciales: 0.000000
$ ./ejemplo /tmp/ejemplo
Datos iniciales: 3.141592
$ ls -ltrh /tmp/ejemplo
-rwx------ 1 ... 94K ... /tmp/ejemplo
$ du -hs /tmp/ejemplo
4,0K	/tmp/ejemplo

Es interesante remarcar el hecho de que el archivo usará únicamente el espacio necesario para alojar los datos escritos o modificados (octetos diferentes de 0). Esto se conoce como archivo disperso (sparse file) y permite reservar, por ejemplo, 200 GB de archivo pero luego usar únicamente 10 MB en zonas no necesariamente colindantes.

cmake_minimum_required( VERSION 2.8 )
add_executable( ejemplo ejemplo.c )
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <assert.h>
int main(int argc, char** argv) {
double *datos;
int fd;
size_t filesize;
/* Si no indicamos el archivo a usar, fallamos la ejecución */
if (argc != 2) {
fprintf(stderr, "Uso: %s <archivo>\n", argv[0]);
return 1;
}
/* Tratamos de crear el archivo nuevo */
fd = open(argv[1], O_RDWR | O_CREAT | O_EXCL, S_IRWXU);
/* Si falla la creación tratamos de abrirlo */
if (fd == -1) {
struct stat st;
/* Abrimos el archivo previo */
fd = open(argv[1], O_RDWR);
assert(fd != -1);
}
/* Reservamos la memoria que deseemos, es el equivalente al "malloc" */
filesize = 12000 * sizeof(double);
/* Creamos el archivo al tamaño deseado */
ftruncate(fd, filesize);
/* Mapeamos el contenido del archivo en memoria */
datos = (double *)mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
assert(datos != MAP_FAILED);
/* Leemos el valor inicial y lo modificamos */
printf("Datos iniciales: %lf\n", datos[0]);
datos[0] = 3.141592;
/* Desmapeamos el archivo de la memoria */
int rc = munmap(datos, filesize);
assert(rc == 0);
/* Cerramos el archivo */
close(fd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment