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.
-
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. -
Länge
- Die Anzahl der Bytes wird abgebildet. -
protect
– Steuert, welche Art von Zugriff erlaubt ist. Zum Beispiel dasPROT_READ
für den Lesezugriff, dasPROT_WRITE
für den Schreibzugriff und dasPROT_EXEC
für die Ausführung. -
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 denaddress
-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.
-
filedes
- Der Dateideskriptor soll abgebildet werden. -
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.