Les fichiers mappés en mémoire peuvent être utilisés pour remplacer l'accès en lecture / écriture ou pour prendre en charge le partage simultané. Lorsque vous les utilisez pour un mécanisme, vous obtenez également l'autre.
Plutôt que de rechercher, d'écrire et de lire dans un fichier, vous le mappez en mémoire et accédez simplement aux bits où vous vous attendez à ce qu'ils soient.
Cela peut être très pratique et, selon l'interface de la mémoire virtuelle, améliorer les performances. L’amélioration des performances peut se produire car le système d’exploitation gère désormais cette ancienne «E / S de fichier» ainsi que tous vos autres accès à la mémoire par programmation, et peut (en théorie) exploiter les algorithmes de pagination et ainsi de suite qu’il utilise déjà pour prendre en charge mémoire virtuelle pour le reste de votre programme. Cela dépend cependant de la qualité de votre système de mémoire virtuelle sous-jacent. Des anecdotes que j'ai entendues dire que les systèmes de mémoire virtuelle Solaris et * BSD peuvent montrer de meilleures améliorations de performances que le système VM de Linux - mais je n'ai pas de données empiriques pour étayer cela. YMMV.
La concurrence entre en jeu lorsque vous considérez la possibilité que plusieurs processus utilisent le même «fichier» via la mémoire mappée. Dans le modèle de lecture / écriture, si deux processus écrivaient dans la même zone du fichier, vous pourriez être à peu près assuré que l'une des données du processus arriverait dans le fichier, écrasant les données de l'autre processus. Vous obtiendrez l'un ou l'autre - mais pas un mélange étrange. Je dois admettre que je ne suis pas sûr qu'il s'agisse d'un comportement imposé par une norme, mais c'est quelque chose sur lequel vous pouvez compter. (C'est en fait une bonne question de suivi!)
Dans le monde cartographié, en revanche, imaginez deux processus à la fois «d'écriture». Ils le font en effectuant des «magasins de mémoire», ce qui entraîne la pagination des données sur le disque par le système d'exploitation - éventuellement. Mais en attendant, on peut s'attendre à ce que des écritures se chevauchent.
Voici un exemple. Disons que j'ai deux processus écrivant tous les deux 8 octets à l'offset 1024. Le processus 1 écrit «11111111» et le processus 2 écrit «22222222». S'ils utilisent des E / S de fichier, alors vous pouvez imaginer, au fond de l'O / S, qu'il y a un tampon plein de 1 et un tampon plein de 2, tous deux dirigés au même endroit sur le disque. L'un d'eux y arrivera le premier, et l'autre une seconde. Dans ce cas, le second l'emporte. Cependant , si j'utilise l'approche des fichiers mappés en mémoire, le processus 1 va aller dans une mémoire de 4 octets, suivie d'une autre mémoire de 4 octets (supposons que ce n'est pas la taille maximale de la mémoire de stockage). Le processus 2 fera la même chose. En fonction du moment où les processus s'exécutent, vous pouvez vous attendre à voir l'un des éléments suivants:
11111111
22222222
11112222
22221111
La solution à cela est d'utiliser l'exclusion mutuelle explicite - ce qui est probablement une bonne idée de toute façon. Vous vous reposiez en quelque sorte sur l'O / S pour faire "la bonne chose" dans le cas d'E / S de fichier en lecture / écriture, de toute façon.
La primitive d'exclusion mutuelle de classification est le mutex. Pour les fichiers mappés en mémoire, je vous suggère de regarder un mutex mappé en mémoire, disponible en utilisant (par exemple) pthread_mutex_init ().
Modifier avec un seul piège: lorsque vous utilisez des fichiers mappés, il est tentant d'incorporer des pointeurs vers les données dans le fichier, dans le fichier lui-même (pensez à la liste liée stockée dans le fichier mappé). Vous ne voulez pas faire cela, car le fichier peut être mappé à différentes adresses absolues à des moments différents ou dans différents processus. Utilisez plutôt des décalages dans le fichier mappé.