Use la función mmap para escribir en la memoria en C

Mehvish Ashiq 12 octubre 2023
  1. la función mmap() en C
  2. Usa mmap() para escribir en la memoria en C
Use la función mmap para escribir en la memoria en C

En este artículo, aprenderemos la función mmap(), cuántos parámetros necesita y cómo usar mmap() para escribir en la memoria en programación C.

la función mmap() en C

Usamos esta función para mapear el espacio de direcciones del proceso y los dispositivos o archivos. La función mmap() solicita un mapeo anónimo y privado grabable de los n bytes de la memoria.

El mapeo anónimo y el mapeo privado significan que no está respaldado por el archivo y no se comparte con otro(s) proceso(s). Para utilizar el mmap(), debemos incluir el archivo de cabecera.

#include <sys/mman.h>

Se necesitan seis argumentos:

void *mmap(void *address, size_t length, int protect, int flags, int filedes,
           off_t offset)

Antes de entrar en el uso de esta función, analicemos los argumentos.

  1. dirección: proporciona la dirección de inicio preferida utilizada para el mapeo. Si no hay otra asignación, el núcleo seleccionará el límite de la página cercana y creará una asignación.

    De lo contrario, el kernel elegirá la nueva dirección. Si el valor de este parámetro es NULL, el núcleo colocará la asignación donde mejor le parezca.

  2. longitud - Se mapea el número de bytes.

  3. proteger - Controla qué tipo de acceso se permite. Por ejemplo, el PROT_READ para acceso de lectura, el PROT_WRITE para acceso de escritura y el PROT_EXEC para ejecución.

  4. flags - Se utiliza para controlar la naturaleza del mapa. Algunas de las banderas comunes y útiles se enumeran a continuación:

    • MAP_SHARED - compartir mapeo con otros procesos.
    • MAP_FIXED - El sistema se ve obligado a utilizar la misma dirección de mapeo dada a través del parámetro dirección.
    • MAP_ANONYMOUS / MAP_ANON - Crea mapeo anónimo.
    • MAP_PRIVATE - El mapeo sería privado y no visible para otros mientras usa esta bandera.
  5. filedes - Se supone que el descriptor del archivo está mapeado.

  6. desplazamiento: la asignación de archivos comienza a partir de este desplazamiento.

Obtenemos 0 si el mmap() funciona con éxito. De lo contrario, se devuelve MAP_FAILED.

Usa mmap() para escribir en la memoria en C

Entendamos mmap() practicando diferentes ejemplos.

Código de ejemplo (para asignación de memoria):

#include <stdio.h>
#include <sys/mman.h>

int main() {
  int N = 5;
  int *ptr = mmap(NULL, N * sizeof(int), PROT_READ | PROT_WRITE,
                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

  if (ptr == MAP_FAILED) {
    printf("Mapping Failed\n");
    return 1;
  }

  for (int i = 0; i < N; i++) ptr[i] = i * 10;

  for (int i = 0; i < N; i++) printf("[%d] ", ptr[i]);

  printf("\n");
  int err = munmap(ptr, 10 * sizeof(int));
  if (err != 0) {
    printf("Unmapping Failed\n");
    return 1;
  }

  return 0;
}

Producción :

[0] [10] [20] [30] [40]

Usamos la función mmap() para asignar la memoria donde estamos usando el PROT_READ | PROT_WRITE protecciones para escribir y leer en una región mapeada.

Usamos el indicador MAP_PRIVATE porque no queremos compartir la región de mapeo con otros procesos y MAP_ANONYMOUS porque no hemos mapeado el archivo.

El descriptor de archivo y el desplazamiento se establecen en 0 por la misma causa.

Código de ejemplo (para comunicación entre procesos):

#include <stdio.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
  int Number = 5;
  int *ptr = mmap(NULL, Number * sizeof(int), PROT_READ | PROT_WRITE,
                  MAP_SHARED | MAP_ANONYMOUS, 0, 0);

  if (ptr == MAP_FAILED) {
    printf("Mapping Failed\n");
    return 1;
  }

  for (int i = 0; i < Number; i++) {
    ptr[i] = i + 7;
  }

  printf("Initial array's values:");
  for (int i = 0; i < Number; i++) {
    printf(" %d", ptr[i]);
  }
  printf("\n");
  pid_t child_pid = fork();

  if (child_pid == 0) {
    // child
    for (int i = 0; i < Number; i++) {
      ptr[i] = ptr[i] * 5;
    }
  } else {
    // parent
    waitpid(child_pid, NULL, 0);
    printf("\nParent:\n");
    printf("Updated array's values:");
    for (int i = 0; i < Number; i++) {
      printf(" %d", ptr[i]);
    }
    printf("\n");
  }

  int err = munmap(ptr, Number * sizeof(int));

  if (err != 0) {
    printf("Unmapping Failed\n");
    return 1;
  }
  return 0;
}

Producción :

Initial array's values: 7 8 9 10 11
Initial array's values: 7 8 9 10 11

Parent:
Updated array's values: 35 40 45 50 55

Inicializamos la matriz con algunos valores inicialmente. Entonces, el proceso de un niño cambia los valores.

Además, los valores son leídos por el proceso principal, que fue cambiado por el proceso secundario porque la memoria asignada se comparte con ambos procesos (secundario y principal). También estamos usando munmap() para eliminar la asignación de memoria.

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Artículo relacionado - C Function