Depuis la page man
,
MAP_ANONYMOUS
The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however, some implementations require
fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The use of MAP_ANONYMOUS in conjunction with
MAP_SHARED is only supported on Linux since kernel 2.4.
À quoi sert l'utilisation de MAP_ANONYMOUS
? Tout exemple serait bon. D'où la mémoire sera mappée?
Il est écrit sur la page man
que The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4.
Comment puis-je partager la mémoire mappée avec MAP_ANONYMOUS avec un autre processus?
Les mappages anonymes peuvent être représentés comme un fichier virtuel mis à zéro. Les mappages anonymes sont simplement de grands blocs de mémoire remplis de zéro prêts à l'emploi. Ces mappages résident en dehors du tas, donc ne contribuent pas à la fragmentation du segment de données.
MAP_ANONYMOUS + MAP_PRIVATE:
MAP_ANONYMOUS + MAP_SHARED:
Sous Linux, il existe deux façons de créer des mappages anonymes:
spécifiez l'indicateur MAP_ANONYMOUS et passez -1 pour fd
addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED)
exit(EXIT_FAILURE);
ouvrez/dev/zero et passez ce fd ouvert
fd = open("/dev/zero", O_RDWR);
addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
(cette méthode est généralement utilisée sur des systèmes comme BSD, qui n'ont pas d'indicateur MAP_ANONYMOUS)
Avantages des mappages anonymes:
- pas de fragmentation de l'espace d'adressage virtuel; après démappage, la mémoire est immédiatement renvoyée au système
- ils sont modifiables en termes de taille d'allocation, d'autorisations et ils peuvent également recevoir des conseils tout comme les mappings normaux
- chaque allocation est un mappage distinct, distinct du tas global
Inconvénients des mappages anonymes:
- la taille de chaque mappage est un multiple entier de la taille de page du système, ce qui peut entraîner un gaspillage de l'espace d'adressage
- la création et le renvoi de mappages entraînent plus de frais généraux que ceux du tas préalloué
si un programme contenant un tel mappage opère un processus, l'enfant hérite du mappage. Le programme suivant illustre ce genre d'héritage:
#ifdef USE_MAP_ANON
#define _BSD_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
/*Pointer to shared memory region*/
int *addr;
#ifdef USE_MAP_ANON /*Use MAP_ANONYMOUS*/
addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
fprintf(stderr, "mmap() failed\n");
exit(EXIT_FAILURE);
}
#else /*Map /dev/zero*/
int fd;
fd = open("/dev/zero", O_RDWR);
if (fd == -1) {
fprintf(stderr, "open() failed\n");
exit(EXIT_FAILURE);
}
addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
fprintf(stderr, "mmap() failed\n");
exit(EXIT_FAILURE);
}
if (close(fd) == -1) { /*No longer needed*/
fprintf(stderr, "close() failed\n");
exit(EXIT_FAILURE);
}
#endif
*addr = 1; /*Initialize integer in mapped region*/
switch(fork()) { /*Parent and child share mapping*/
case -1:
fprintf(stderr, "fork() failed\n");
exit(EXIT_FAILURE);
case 0: /*Child: increment shared integer and exit*/
printf("Child started, value = %d\n", *addr);
(*addr)++;
if (munmap(addr, sizeof(int)) == -1) {
fprintf(stderr, "munmap()() failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
default: /*Parent: wait for child to terminate*/
if (wait(NULL) == -1) {
fprintf(stderr, "wait() failed\n");
exit(EXIT_FAILURE);
}
printf("In parent, value = %d\n", *addr);
if (munmap(addr, sizeof(int)) == -1) {
fprintf(stderr, "munmap()() failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
Sources:
L'interface de programmation Linux
Chapitre 49: Mappages de mémoire,
Auteur: Michael Kerrisk
Programmation système Linux (3e édition)
Chapitre 8: Gestion de la mémoire,
Auteur: Robert Love