mmap - mmap

I computing , mmap(2)er en POSIX -kompatibel Unix -system opkald , der kortlægger filer eller enheder i hukommelsen. Det er en metode til hukommelseskortet fil I / O. Den implementerer personsøgning, fordi filindholdet ikke læses direkte fra disken og oprindeligt slet ikke bruger fysisk RAM. De faktiske læsninger fra disken udføres på en " doven " måde, efter at der er adgang til en bestemt placering. Når hukommelsen ikke længere er nødvendig, er det vigtigt for munmap(2)henvisningerne. Beskyttelsesoplysninger kan administreres ved hjælp af mprotect(2), og speciel behandling kan håndhæves ved hjælp af madvise(2).

I Linux , MacOS og BSD'er , mmapkan skabe flere typer af tilknytninger. Andre operativsystemer understøtter muligvis kun en delmængde af disse; for eksempel er delte tilknytninger muligvis ikke praktiske i et operativsystem uden en global VFS- eller I / O-cache.

Historie

Det originale design af hukommelseskortede filer kom fra TOPS-20- operativsystemet. mmapog tilknyttede systemopkald blev designet som en del af Berkeley Software Distribution (BSD) version af Unix. Deres API var allerede beskrevet i 4.2BSD-systemmanualen, selvom den hverken blev implementeret i denne udgivelse eller i 4.3BSD. Sun Microsystems havde imidlertid implementeret denne meget API i deres SunOS- operativsystem. BSD-udviklerne ved UC Berkeley anmodede Sun om at donere implementeringen, men disse samtaler førte aldrig til nogen overførsel af kode; 4.3BSD-Reno blev sendt i stedet med en implementering baseret på det virtuelle hukommelsessystem fra Mach .

Filstøttet og anonym

Filbaseret kortlægning kortlægger et område af processens virtuelle hukommelse til filer; dvs. at læse disse hukommelsesområder får filen til at læses. Det er standardkortlægningstypen.

Anonym kortlægning kortlægger et område af processens virtuelle hukommelse, der ikke understøttes af nogen fil. Indholdet initialiseres til nul. I denne henseende svarer en anonym kortlægning til mallocog bruges i nogle malloc(3)implementeringer til bestemte tildelinger. Imidlertid er anonyme tilknytninger ikke en del af POSIX-standarden, men implementeret af næsten alle operativsystemer af MAP_ANONYMOUSog MAP_ANONflag.

Hukommelsessynlighed

Hvis kortlægningen deles ( MAP_SHAREDflaget er indstillet), bevares det på tværs af et gaffel (2) systemopkald. Dette betyder, at skrivning til et kortlagt område i en proces er umiddelbart synlig i alle relaterede (forældre, barn eller søskende) processer. Hvis kortlægningen deles og bakkes op af en fil (ikke MAP_ANONYMOUS), garanteres det underliggende filmedium kun, når det er msync (2) 'ed.

Hvis kortlægningen er privat ( MAP_PRIVATEflag er indstillet), vil ændringerne hverken blive set af andre processer eller skrevet til filen.

En proces, der læser fra eller skriver til den underliggende fil, vil ikke altid se de samme data som en proces, der har kortlagt filen, da segmentet af filen kopieres til RAM og regelmæssigt skylles til disken. Synkronisering kan tvinges med msyncsystemopkaldet.

mmap (2) ing-filer kan reducere hukommelsesomkostningerne betydeligt for applikationer, der har adgang til den samme fil; de kan dele hukommelsesområdet, som filen omfatter, i stedet for at indlæse filen for hver applikation, der ønsker adgang til den. Dette betyder, at mmap (2) undertiden bruges til interprocess kommunikation (IPC). På moderne operativsystemer foretrækkes mmap (2) typisk frem for System V IPC Shared Memory- faciliteten.

Den største forskel mellem System V delt hukommelse (shmem) og hukommelseskortet I / O (mmap) er, at System V delt hukommelse er vedvarende: medmindre det eksplicit fjernes af en proces, holdes det i hukommelsen og forbliver tilgængeligt, indtil systemet lukkes ned . mmap'd-hukommelse er ikke vedvarende mellem programudførelser (medmindre den er bakket op af en fil).

Eksempel på brug under programmeringssproget C

#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* This example shows how an mmap of /dev/zero is equivalent to
   using anonymous memory (MAP_ANON) not connected to any file.
   N.B. MAP_ANONYMOUS or MAP_ANON are supported by most UNIX
   versions, removing the original purpose of /dev/zero.
*/
/* Does not work on OS X or macOS, where you can't mmap over /dev/zero */
int main(void)
{
        const char str1[] = "string 1";
        const char str2[] = "string 2";
        pid_t parpid = getpid(), childpid;
        int fd = -1;
        char *anon, *zero;

        if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
                err(1, "open");

        anon = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
        zero = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

        if (anon == MAP_FAILED || zero == MAP_FAILED)
                errx(1, "either mmap");

        strcpy(anon, str1);
        strcpy(zero, str1);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        switch ((childpid = fork())) {
        case -1:
                err(1, "fork");
                /* NOTREACHED */
        case 0:
                childpid = getpid();
                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                sleep(3);

                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                munmap(anon, 4096);
                munmap(zero, 4096);
                close(fd);
                return EXIT_SUCCESS;
        }

        sleep(2);
        strcpy(anon, str2);
        strcpy(zero, str2);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        munmap(anon, 4096);
        munmap(zero, 4096);
        close(fd);
        return EXIT_SUCCESS;
}

prøve output:

PID 22475:      anonymous string 1, zero-backed string 1
PID 22476:      anonymous string 1, zero-backed string 1
PID 22475:      anonymous string 2, zero-backed string 2
PID 22476:      anonymous string 2, zero-backed string 2

Se også

Referencer

Yderligere læsning