Je suis confus au sujet des fichiers mappés en mémoire, j'ai donc quelques questions que je serais très heureux si vous pouviez m'aider.
- Disons que je navigue vers un répertoire de mon système de fichiers et qu'il y a un fichier dans ce répertoire. Est-il possible que ce fichier pointe vers une région de la mémoire principale, au lieu de pointer vers une région du disque?
- Si cela est possible, est-ce ce que nous appelons un «fichier mappé en mémoire»?
- Quelle serait la signification du déplacement d'un tel fichier dans le système de fichiers (c'est-à-dire, un
mv
tel fichier d'un répertoire à un autre)? Ce que je comprends, étant donné que le fichier est mappé en mémoire, le ou les processus interagissant avec le fichier écrivent toujours dans une région prédéfinie de la mémoire principale, et lorsque nous ouvrons ce fichier (par exemple en utilisantvim
), nous lisons cette région de principal mémoire (donc, aucun disque n'est impliqué). Par conséquent, peu importe où nous déplaçons le fichier, il fonctionnera toujours correctement, non? Si oui, le déplacement du fichier dans le système de fichiers a-t-il une signification? - Existe-t-il une commande qui indiquerait si un fichier est mappé en mémoire?
- Enfin, si j'ouvre un fichier mappé en mémoire avec
vim
, y apporte des modifications et l'enregistre et le fermevim
, que se passera-t-il? Mes modifications seront-elles simplement écrites dans la mémoire principale? Si tel est le cas, les autres processus qui utilisent ce fichier verront-ils les modifications que je viens d'apporter? D'après mon expérience, les autres processus n'ont pas vu les modifications que j'ai apportées au fichier lorsque j'ai apporté des modifications au fichier avecvim
. Quelle est la raison pour ça?
Réponses:
Les fichiers mappés en mémoire fonctionnent dans l'autre sens. Le mappage de la mémoire n'est pas une propriété du fichier, mais un moyen d'accéder au fichier: un processus peut mapper le contenu d'un fichier (ou un sous-ensemble de celui-ci) dans son espace d'adressage. Cela facilite la lecture et l'écriture dans le fichier; cela implique simplement de lire et d'écrire en mémoire. Le fichier lui-même, sur disque, est identique à tout autre fichier.
Pour configurer cela, les processus utilisent la
mmap
fonction. Cela peut également être utilisé à d'autres fins, comme le partage de mémoire entre les processus.la source
mv
.mv
changent simplement les entrées de répertoire, pas les inodes (quand il déplace des fichiers sur le même système de fichiers).lsof
. Il ne disparaît que lorsque le processus appelle munmap (), ou quitte (ou remplace le mappage par un autre en utilisant mmap (MAP_FIXED) ...)Un fichier mappé en mémoire n'est pas (nécessairement) sauvegardé par la mémoire. Il peut parfaitement vivre sur un disque. En fait, l'emplacement d'un fichier n'est pas une propriété du fichier lui-même mais du système de fichiers dans lequel il réside.
Le mappage d'un fichier en mémoire est une opération qu'un processus peut effectuer pour charger une partie du fichier en mémoire. Le résultat ressemble à une région de mémoire normale, sauf que lorsque le processus lit ou écrit dans cette région, il lit et écrit dans le fichier. Si vous ouvrez un fichier, mappez-le en mémoire, écrivez-le et enregistrez-le, la modification se fera sur le fichier, sur le disque (s'il vit sur un disque, bien sûr).
Ceci peut être utilisé par exemple lorsque vous savez que vous avez beaucoup d'accès à faire sur un fichier, qui ne va pas être séquentielle, être la cause , il peut être plus facile et plus efficace de faire des lectures et écritures en mémoire plutôt que d' effectuer
read
,write
, et lesllseek
appels système. Le seul problème avec cette méthode est que vous ne pouvez pas vraiment l'utiliser si le fichier doit être lu ou écrit par plusieurs processus simultanément. Les résultats seraient imprévisibles.Je ne connais aucune commande qui puisse vous dire si un fichier est actuellement mappé. Vous pouvez cependant inspecter les mappages d'un processus dans
/proc/<pid>/maps
(si votre système en dispose).Pour répondre à votre deuxième question, lorsque vous ouvrez un fichier, même si vous le déplacez dans le système de fichiers, les processus qui l'ont ouvert peuvent toujours l'utiliser. Ce qui se passe, c'est qu'un fichier ne dépend pas de ses entrées dans les systèmes de fichiers. Tant qu'un fichier est ouvert, vous disposez d'un "descripteur", un descripteur de fichier, qui vous permet de lire et d'écrire dessus, même si son chemin dans le système de fichiers change. Un fichier ne disparaît que s'il n'a aucune entrée dans le système de fichiers et qu'aucun processus ne contient de descripteur de fichier.
la source
/proc/<pid>/maps
. - Pourvu que ce processus vive sur un système qui a/proc
pour commencer. OpenBSD ne le fait pas et FreeBSD le supprime progressivement. De plus, FreeBSD a/proc/<pid>/map
au lieu de/proc/<pid>/maps
.La
lsof
commande vous montrera tous les fichiers actuellement utilisés par le système. La colonne "FD" contiendra "mem" si le fichier est mappé en mémoire. Vous pouvez donc récupérer la sortie de cette commande pour le nom de fichier qui vous intéresse.la source
lsof -ad mem /path/to/file
lsof -ad mem,txt /path/to/file
comme les fichiers en cours d'exécution ont également des parties d'entre eux mmappées dans l'espace d'adressage du processus mais apparaissent commetxt
dans lalsof
sortie.Vous semblez confondre le mappage de la mémoire avec des fichiers dans des systèmes de fichiers résidant en mémoire, ainsi que d'autres concepts tels que la façon dont les processus conservent l'accès aux fichiers même lorsqu'ils sont déplacés.
Je vais aller question par question pour voir si je peux clarifier les choses.
Il pointe vers la mémoire principale si elle se trouve sur un système de fichiers résidant en mémoire, comme procfs qui est généralement monté sur / proc, ou sysfs qui est sur / sys, ou tmpfs qui est parfois sur / tmp.
Non. Comme l'a dit stephen-kitt, "mappage de mémoire" fait référence à un moyen d'accéder à un fichier en le "mappant" sur la mémoire principale et en y travaillant plutôt que de lire et d'écrire des morceaux à la fois via des fonctions comme read () et écrire().
Si vous le déplacez dans le même système de fichiers, vous ne faites que déplacer une référence, un inode d'un répertoire à un autre. S'il y a des programmes qui avaient déjà ouvert ce fichier, ils accéderont toujours au même fichier car ils ont déjà l'inode à portée de main via un descripteur de fichier. C'est ce qui s'est produit avec le fichier nom_table.idb que vous avez mentionné dans un commentaire.
Wossname a déjà répondu à cette question pour les fichiers mappés en mémoire.
lsof
vous indiquera quels processus ont le fichier mappé en mémoire.Pour savoir si un fichier se trouve dans un système de fichiers résidant en mémoire, vous pouvez utiliser
df
oumount
pour répertorier les systèmes de fichiers et leurs points de montage. Il vous suffit de savoir quels types de systèmes de fichiers résident en mémoire en les recherchant (par exemple dans wikipedia).Personnellement, je n'ai pas utilisé lammap
fonction dans un programme C, mais si je comprends bien le survolman mmap
etinfo mmap
, il n'y a aucune magie impliquée dans le maintien de la représentation en mémoire en synchronisation. Dans sa forme de base, l'appel de mmap copie le contenu du fichier en mémoire etmsync
est utilisé pour le réécrire de la mémoire sur le disque. Si le fichier sur disque change, rien n'est en place pour le détecter et modifier automatiquement la représentation en mémoire dans tous les processus qui l'ont mappé.EDIT: Il s'avère que mmap () essaie en fait de garder la représentation en mémoire synchronisée dans certaines conditions. Si la carte est uniquement lue, elle sera synchronisée même lorsque d'autres processus écrivent dans le fichier. S'il est écrit dans (en l'attribuant à la région de mémoire), ce qui se passe dépend du drapeau MAP_SHARED ou MAP_PRIVATE apparemment obligatoire fourni à mmap (). Si MAP_PRIVATE est fourni, la carte se dérobe à partir de la représentation sur disque et cesse d'être synchronisée jusqu'à ce que vous utilisiez msync (). Si MAP_SHARED est fourni, les mises à jour sont rendues visibles aux autres processus qui ont le fichier mappé, ainsi que (bien que cela ne soit pas nécessairement immédiat) la représentation sur disque.
Je viens d'ouvrir vim sur un fichier existant
e
et d' exécuter la commande:w
, tout en ayantinotifywait -m .
exécuté dans un autre terminal. Parmi quelques morceaux étranges, c'est la partie importante dont je suis sortiinotifywait
.Vim crée un nouveau fichier et supprime l'ancien. Pourquoi cela fait-il au lieu de modifier le fichier est hors de portée de cette question, mais le fait est qu'il s'agit d'un nouveau fichier et donc d'un nouvel inode.
Maintenant, qu'entendez-vous par d'autres processus utilisant ce fichier? Si vous voulez dire les processus qui ont ouvert le fichier pendant que vous le faites, non, ils ne verront pas les modifications. En effet, bien qu'ils aient ouvert un fichier avec le même chemin d'accès, ils ne sont pas le même fichier. Si vous voulez dire les processus qui peuvent ouvrir le fichier après cela, alors oui, ils verront les changements. Ils ouvriront le nouveau fichier que vous avez créé.
Il est important de noter que même si les programmes peuvent sembler avoir un fichier ouvert sur l'interface utilisateur, cela ne signifie pas nécessairement qu'ils gardent le fichier ouvert dans le processus. Vim en est un exemple, comme illustré ci-dessus.
la source
write
fonction est de modifier les données du fichier. Cela peut signifier ou non changer le contenu du disque, mais quoi que cela implique, c'est la responsabilité du système de fichiers de bien faire les choses. Dans ce cas, cela impliquerait de modifier la page de mémoire mappée et de la marquer comme sale.