Bonjour à tous,
voila si je veux lire un fichier je peux faire :
int fd = open("fichier_a_lire.txt", O_RDONLY);
et ensuite je peux faire :
read(fd, buffer, 256);
ou faire
void* addr = mmap(NULL,length_of_fichier_a_lire,…, fd, 0);
strncpy( buffer, addr, 256);
mais c'est quoi le mieux?
dans les deux cas le fichier est chargé en RAM par le noyau via l'appel systeme open, donc pourquoi s’embêter avec mmap ?
merci de vos éclaircissements
# quelques pistes ...
Posté par LaBienPensanceMaTuer . Évalué à 5. Dernière modification le 23 avril 2019 à 18:17.
Pour un usage classique (aka lire un fichier), je suis pas sûr en effet qu'il y ai un grand intérêt: c'est à ta convenance mais aussi et surtout en fonction du système hôte car il faut se souvenir que linux tourne sur du hard embarqué avec parfois très peu de RAM: dans ce contexte, mapper l'intégralité d'un fichier en mémoire est parfois impossible.
Pour tout les usages ou tu vas préferer utiliser un pointeur (plus souple, te permet de te ballader facilement) plutôt qu'un fd (séquentiel, rewind & co), mmap sera probablement plus adapté.
De mémoire, mmap() peut aussi être utilisé pour de la communication interprocess… (genre j'ouvre un shm qui me donne un fd, puis je mappe ce fd à coup de mmap et hop, j'ai un pointeur partagé entre mes deux process).
En espérant t'avoir déjà donné quelques éléments …
[^] # Re: quelques pistes ...
Posté par David Marec . Évalué à 5.
En tout cas, si c'est juste pour faire une copie du mapping dans un autre buffer( ici le
strncpy
) , ça ne sert pas à grand chose.[^] # Re: quelques pistes ...
Posté par freem . Évalué à 2.
read
aussi, vu que les sockets AF_UNIX sont des mécanismes d'IPC.Bon, j'avoue, cette remarque est un prétexte pour te poser d'autres questions:
Donc,
mmap
serait moins efficace dans ces cas queread
? Cela n'impliquerait-il pas d'avoir une configuration pour read adéquate?Je suis réellement curieux, étant à la croisée entre de vieux souvenirs de cours, ma démerde pendant une décennie, et un taf qui me demande maintenant de faire de l'IPC…
Pour ajouter de l'eau à ton moulin, dans ton sens, si tu mappes une zone mémoire entre deux processus, il va aussi te falloir gérer les accès concurrentiels, et du coup, utiliser un socket est nettement plus simple (c'est, en gros, un pipe), mais sera effectivement plus lourd qu'un mémoire partagée entre 2 processus.
[^] # Re: quelques pistes ...
Posté par David Marec . Évalué à 2.
Cela reste du traitement par flux.
C'est assez peu adapté lors de gros échanges de données et lorsque que l'on doit pouvoir se positionner dans la zone (
fseek/lseek
). Je pense en particulier aux traitements vidéo où l'on doit entrelacer et dé-entrelacer des blocs.C'est là que l'on utilise
mmap
, associé à une mémoire partagée (shm_
), par exemple.S'il s'agit d'un fichier, on peut aussi partager le descripteur de fichier via une socket unix.
Bref, sans plus de détails, on ne pas dire ce qui est "mieux".
Et si l'on cherche à atteindre ou améliorer des performances (consommation et/ou vitesse), il faut faire des mesures.
[^] # Re: quelques pistes ...
Posté par LaBienPensanceMaTuer . Évalué à 3.
Yep, tout à fait.
Après, j'imagine qu'un segment de mémoire partagé est peut être plus performant qu'une socket (mais ce n'est que présomption)
Bein, à mon taf on a du hard avec 8MiB de RAM. Autant te dire que mapper un fichier ne serait ce que de 1 ou 2 MiB à coup de mmap() met un vilain coup au système :-)
Bien sûr, mais disons que le segment de mémoire partagé ne t'impose pas un scénario/protocole de communication contrairement au socket (aka proc-A envoie un message X à proc-B et bloque ensuite en l'attente d'une réponse Y).
A l'inverse, l'utilisation de sendmsg() avec un socket peut faciliter le développement (puisque les messages transmis sont directement mappable sur une structure C)… chose qui reste cependant possible avec un mmap() en utilisant un cast.
Puisque le fond de ton message semble concerné l'IPC, je vais dériver un peu sur ce sujet.
A mon humble opinion, il n'y a pas de solution miracle ou d'IPC à tout faire. En vrac et sans être exhaustif, je dirai que:
Si tu veux qu'un processus X offre un "service" à un process Y sans connaitre Y au préalable, je partirai sur des sockets unix en effet.
Si tu veux échanger des données que tu vas au préalable manipuler à coup de transformation de pointeur, mmap() est probablement plus adapté.
Si le système cible est performant (au minimum une carte avec un ARM AXX), je partirai sur un composant plus haut niveau:
Pour conclure, en 2019, je m'embêterai pas à écrire moi même un système d'IPC à moins que:
* Ce soit un délire personnel, pour le plaisir (mais faut être un peu maso ;-).
* Le système cible soit vraiment très contraignant (peu de RAM en particulier).
[^] # Re: quelques pistes ...
Posté par LaBienPensanceMaTuer . Évalué à 2. Dernière modification le 24 avril 2019 à 11:02.
supprimé par l'auteur.
# mmap vs malloc
Posté par gUI (Mastodon) . Évalué à 4. Dernière modification le 24 avril 2019 à 08:29.
De ce que j'ai compris,
mmap
sert aux gros fichiers. En effet, avecmmap
tu n'as pas de mise en mémoire du fichier, il n'y a pas demalloc
gigantesque. C'est le kernel qui ira lire quand il le faut les données sur le disque (par page mémoire ?), mais toi tu te contentes de gérer "comme si" tout était mis en RAM.Dans le cas de 256 octets que tu veux absolument mettre en RAM, aucune utilité, fais simplement un
read
, ne serait-ce que parce que c'est bcp plus lisible comme code.A vérifier, je suis pas spécialiste, mais je n'ai vu mmap utilisé que sur des gros fichiers en tous cas.
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: mmap vs malloc
Posté par Matthieu Moy (site web personnel) . Évalué à 4.
C'est à peu près ça.
Le problème avec
open
+read
, c'est que tu vas typiquement faire :Le contenu du fichier apparaîtra deux fois en RAM : une fois dans le cache, au niveau du kernel, et une fois dans le processus, pour la variable
buffer
. Avecmmap
, c'est la même RAM physique qui est utilisée pour le cache pour la mémoire de travail du processus (une lecture à un endroit du fichier qui n'est pas encore chargée en RAM va déclencher un chargement dans le cache, une écriture va écrire dans le cache qui sera écrite sur disque un peu plus tard). Bien sûr, ça veut aussi dire que si on écrit dans cette zone de RAM, on écrit directement dans le fichier, donc ça n'est pas applicable si on veut faire des modifications locales non-visibles par les autres processus.[^] # Re: mmap vs malloc
Posté par David Marec . Évalué à 4.
Ce n'est pas la taille qui compte.
Ou plutôt, c'est aussi utile si l'on veut éviter de multiplier les appels à
read
.Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.