Quelle est la différence entre écrire sur un fichier et une mémoire mappée?
j'ai les questions suivantes concernant le traitement des fichiers et leur mise en correspondance (mmap
):
- Nous savons que si nous créons un fichier et écrire dans ce fichier, alors soit les moyens que nous écrivons à la mémoire. Alors pourquoi associer ce fichier à la mémoire en utilisant
mmap
et puis les écrire? - si c'est à cause de la protection que nous obtenons en utilisant
mmap
-PROT_NONE
,PROT_READ
,PROT_WRITE
, alors le même niveau de protection peut aussi être atteint en utilisant des fichiers.O_RDONLY
,O_RDWR
etc. Alors pourquoimmap
? - y a-t-il un avantage particulier que nous obtenons sur les fichiers de mappage vers la mémoire, et ensuite l'utiliser? Plutôt que de simplement créer un fichier et lui écrire?
- Enfin, supposons que nous
mmap
un fichier en mémoire, si nous écrivons à cet endroit de mémoire retourné par mmap, est-ce qu'il écrit aussi simultanément à ce fichier?
Veuillez m'aider à répondre à toutes les requêtes.
Merci beaucoup en avance.
*EDIT: le Partage de fichiers entre les threads *
autant Que je sache, si nous partager un fichier entre deux threads (pas de processus) alors il est conseillé d' mmap
en mémoire et ensuite de l'utiliser, plutôt que d'utiliser directement le fichier.
Mais nous savons que l'utilisation d'un fichier, il est sûrement dans la mémoire principale, alors pourquoi encore le filetage doit être mmaped?
4 réponses
un fichier mappé en mémoire est en fait partiellement ou totalement mappé en mémoire (RAM), alors qu'un fichier auquel vous écrivez serait écrit en mémoire et ensuite envoyé sur le disque. Un fichier mappé en mémoire est pris à partir du disque et placé dans la mémoire explicitement pour la lecture et/ou l'écriture. Il reste là jusqu'à ce que tu le démontes.
L'accès au disque est plus lent, donc quand vous avez écrit à un fichier, il sera jeté sur le disque et ne résidera plus en RAM, ce qui signifie que la prochaine fois que vous aurez besoin du fichier, vous pourriez alors que dans les fichiers mappés en mémoire, vous savez que le fichier est en RAM et que vous pouvez y accéder plus rapidement qu'avec un disque.
en outre, les fichiers mappés mememory sont souvent utilisés comme mécanisme de la CIB, de sorte que deux processus ou plus peuvent facilement partager le même fichier et lire/écrire. (en utilisant les mécanismes sycnh nécessaires)
quand vous avez besoin de lire un fichier souvent, et que ce fichier est assez grand, il peut être avantageux de le mapper en mémoire de sorte que vous avez un accès plus rapide à avoir à aller l'ouvrir et l'obtenir à partir du disque à chaque fois.
EDIT:
cela dépend sur vos besoins, quand vous avez un fichier qui devra être consulté très fréquemment par différents threads, alors je ne suis pas sûr que la cartographie de la mémoire du fichier sera nécessairement une bonne idée, du point de vue que, vous aurez besoin de synchroniser l'accès à ce fichier mmap'ed si vous le souhaitez lui écrire, aux mêmes endroits à partir de différents threads. Si cela se produit très souvent, il pourrait s'agir d'un point de désaccord sur les ressources.
juste la lecture du fichier, alors cela pourrait être une bonne solution, parce que vous n'avez pas vraiment besoin de synchroniser l'accès, si vous êtes lecture à partir de plusieurs threads. Dès que vous commencez à écrire, vous dois utiliser des mécanismes de synchronisation.
je suggère, que chaque thread fasse son propre accès au fichier d'une manière locale, si vous devez écrire dans le fichier, tout comme vous le faites avec n'importe quel autre fichier. De cette façon, il réduit le besoin de synchronisation de thread et la probabilité de bogues difficiles à trouver et à déboguer.
1) Vous avez mal compris l'appel système write(2). write () n'écrit pas, il copie simplement un contenu-tampon dans la chaîne de buffer OS et le marque comme sale. L'un des fils D'OS (bdflush IIRC) récupérera ces tampons, les écrira sur le disque et Remuera quelques drapeaux. tard. Avec mmap, vous accédez directement au tampon D'OS (mais si vous modifiez son contenu, il sera marqué dirty, too)
2) Il ne s'agit pas de protection, il s'agit de mettre des drapeaux dans le pagetable entrée.
3) vous évitez le double tampon. Vous pouvez aussi traiter le fichier en termes de caractères au lieu de blocs, ce qui est parfois plus pratique
4) ce sont les tampons système (connectés dans votre espace d'adresse) que vous utilisez. Le système peut ou peut ne pas avoir écrit des pièces de ce disque.
5) Si les threads appartiennent au même processus et partagent les pagetables et l'adresse-espace, Oui.
une raison peut être que vous avez du code (legacy) qui est configuré pour écrire dans un tampon de données, et puis ce tampon est écrit pour le fichier en une seule fois à la fin. Dans ce cas, à l'aide de
mmap
enregistrera au moins une copie des données, car le système D'exploitation peut écrire directement le tampon sur le disque. Tant qu'il ne s'agit que d'écriture de fichier, je ne peux pas (encore) imaginer d'autres raisons pour lesquelles vous voudriez utilisermmap
.non, la protection n'est pas pertinente ici dire.
il peut enregistrer une ou deux copies des données à partir d'un tampon d'application vers un tampon de libc vers un tampon D'OS, voir point 1. Cela pourrait faire une différence de performance lors de l'écriture de grandes quantités de données.
Non. Autant que je sache, l'OS est libre d'écrire les données à tout moment qu'il veut, tant que les données ont été écrites sur le disque après un appel à
msync
oumunmap
sur cette région de mémoire. (Et pour la plupart des fichiers, il est probable qu'il n'écrira rien dans entre la majorité du temps, pour des raisons de performance: écrire un bloc entier sur un disque parce qu'un octet a changé est assez cher, en particulier s'il faut s'attendre à ce que beaucoup plus de modifications au bloc se produira dans un proche avenir.)
dans la plupart des cas, vous devriez considérer le fichier de mappage de mémoire comme de la mémoire avec laquelle vous travaillez. Vous ne devez vous soucier que des cas spéciaux comme la synchronisation avec le disque. C'est le même type de stockage que la mémoire, mais il peut être initialisé à partir du fichier et stocké dans le fichier chaque fois que vous avez besoin.