Verwenden Sie die mmap-Funktion, um in C in den Speicher zu schreiben

Mehvish Ashiq 12 Oktober 2023
  1. die Funktion mmap() in C
  2. Verwenden Sie mmap(), um in C in den Speicher zu schreiben
Verwenden Sie die mmap-Funktion, um in C in den Speicher zu schreiben

In diesem Artikel lernen wir die Funktion mmap() kennen, wie viele Parameter sie benötigt und wie man mmap() verwendet, um in der C-Programmierung in den Speicher zu schreiben.

die Funktion mmap() in C

Wir verwenden diese Funktion, um den Adressraum des Prozesses und entweder die Geräte oder Dateien abzubilden. Die Funktion mmap() fordert eine beschreibbare anonyme und private Zuordnung der n Bytes des Speichers an.

Das anonyme Mapping und das private Mapping bedeuten, dass es nicht von der Datei unterstützt wird und nicht mit anderen Prozessen geteilt wird. Um mmap() zu verwenden, müssen wir die Header-Datei einbinden.

#include <sys/mman.h>

Es braucht sechs Argumente:

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

Bevor wir uns mit der Verwendung dieser Funktion befassen, wollen wir die Argumente besprechen.

  1. Adresse – Liefert die bevorzugte Startadresse, die für die Zuordnung verwendet wird. Wenn es keine andere Zuordnung gibt, wählt der Kernel die nahe gelegene Seitengrenze aus und erstellt eine Zuordnung.

    Andernfalls wählt der Kernel die neue Adresse. Wenn der Wert für diesen Parameter NULL ist, platziert der Kernel das Mapping dort, wo er es für richtig hält.

  2. Länge - Die Anzahl der Bytes wird abgebildet.

  3. protect – Steuert, welche Art von Zugriff erlaubt ist. Zum Beispiel das PROT_READ für den Lesezugriff, das PROT_WRITE für den Schreibzugriff und das PROT_EXEC für die Ausführung.

  4. flags - Es wird verwendet, um die Art der Karte zu steuern. Einige der gebräuchlichen und nützlichen Flags sind unten aufgeführt:

    • MAP_SHARED - Mapping mit anderen Prozessen teilen.
    • MAP_FIXED – Das System wird gezwungen, dieselbe Mapping-Adresse zu verwenden, die über den address-Parameter angegeben wurde.
    • MAP_ANONYMOUS / MAP_ANON - Es erstellt eine anonyme Zuordnung.
    • MAP_PRIVATE - Das Mapping wäre privat und für andere nicht sichtbar, wenn dieses Flag verwendet wird.
  5. filedes - Der Dateideskriptor soll abgebildet werden.

  6. offset - Das File-Mapping beginnt ab diesem Offset.

Wir erhalten 0, wenn mmap() erfolgreich funktioniert. Andernfalls wird MAP_FAILED zurückgegeben.

Verwenden Sie mmap(), um in C in den Speicher zu schreiben

Lassen Sie uns mmap() verstehen, indem wir verschiedene Beispiele üben.

Beispielcode (für Speicherbelegung):

#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;
}

Ausgang:

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

Wir verwenden die Funktion mmap(), um den Speicher zuzuweisen, wo wir die Funktion PROT_READ | PROT_WRITE-Schutz zum Schreiben und Lesen in einer zugeordneten Region.

Wir verwenden das Flag MAP_PRIVATE, weil wir die Zuordnungsregion nicht mit anderen Prozessen teilen möchten, und das Flag MAP_ANONYMOUS, weil wir die Datei nicht zugeordnet haben.

Der Dateideskriptor und der Offset werden aus demselben Grund auf 0 gesetzt.

Beispielcode (für Interprozesskommunikation):

#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;
}

Ausgang:

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

Wir initialisieren das Array zunächst mit einigen Werten. Dann ändert der Prozess eines Kindes die Werte.

Außerdem werden die Werte vom übergeordneten Prozess gelesen, die vom untergeordneten Prozess geändert wurden, da der zugeordnete Speicher von beiden (untergeordneten und übergeordneten) Prozessen gemeinsam genutzt wird. Wir verwenden auch die munmap(), um die Speicherzuordnung zu entfernen.

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

Verwandter Artikel - C Function