Ich bin verwirrt über speicherabgebildete Dateien, daher habe ich einige Fragen, über die ich mich sehr freuen würde, wenn Sie mir helfen könnten.
- Angenommen, ich navigiere zu einem Verzeichnis in meinem Dateisystem und es befindet sich eine Datei in diesem Verzeichnis. Ist es möglich, dass diese Datei auf eine Region im Hauptspeicher verweist, anstatt auf eine Region auf der Festplatte?
- Wenn dies möglich ist, nennen wir dies "speicherabgebildete Datei"?
- Was würde es bedeuten, eine solche Datei im Dateisystem zu verschieben (dh
mv
eine solche Datei von einem Verzeichnis in ein anderes zu verschieben)? Ich verstehe, dass, da die Datei speicherabgebildet ist, die mit der Datei interagierenden Prozesse immer in einen vordefinierten Bereich des Hauptspeichers schreiben. Wenn wir diese Datei öffnen (z. B. mitvim
), lesen wir diesen Bereich des Hauptspeichers Speicher (also ist keine Festplatte beteiligt). Unabhängig davon, wohin wir die Datei verschieben, funktioniert sie immer richtig, oder? Wenn ja, hat das Verschieben der Datei im Dateisystem eine Bedeutung? - Gibt es einen Befehl, der anzeigt, ob eine Datei dem Speicher zugeordnet ist?
- Was passiert , wenn ich eine Speicherzuordnungsdatei mit öffne
vim
, einige Änderungen daran vornehme und speichere und schließevim
? Werden meine Änderungen einfach in den Hauptspeicher geschrieben? Wenn dies der Fall ist, werden andere Prozesse, die diese Datei verwenden, die Änderungen sehen, die ich gerade vorgenommen habe? Nach meiner Erfahrung haben die anderen Prozesse die Änderungen, die ich an der Datei vorgenommen habe, nicht gesehen, als ich einige Änderungen an der Datei mit vorgenommen habevim
. Was ist der Grund dafür?
Antworten:
Speicherzugeordnete Dateien funktionieren umgekehrt. Die Speicherzuordnung ist keine Eigenschaft der Datei, sondern eine Möglichkeit, auf die Datei zuzugreifen: Ein Prozess kann den Inhalt einer Datei (oder eine Teilmenge davon) in ihren Adressraum abbilden. Dies erleichtert das Lesen und Schreiben in die Datei. Dazu muss man einfach im Gedächtnis lesen und schreiben. Die Datei selbst auf der Festplatte ist genauso wie jede andere Datei.
Um dies einzurichten, verwenden Prozesse die
mmap
Funktion. Dies kann auch für andere Zwecke verwendet werden, z. B. zum Teilen des Speichers zwischen Prozessen.quelle
mv
.mv
ändern einfach die Verzeichniseinträge, nicht die Inodes (wenn Dateien auf demselben Dateisystem verschoben werden).lsof
. Es verschwindet nicht, bis der Prozess munmap () aufruft oder beendet (oder das Mapping mit mmap (MAP_FIXED) durch ein anderes ersetzt ...)Eine Speicherzuordnungsdatei wird nicht (unbedingt) vom Speicher gesichert. Es kann perfekt auf einer Festplatte leben. Wo eine Datei lebt, ist eigentlich keine Eigenschaft der Datei selbst, sondern des Dateisystems, in dem sie sich befindet.
Das Zuordnen einer Datei im Speicher ist eine Operation, die ein Prozess ausführen kann, um einen Teil der Datei in den Speicher zu laden. Das Ergebnis sieht aus wie ein regulärer Speicherbereich, außer dass der Prozess beim Lesen oder Schreiben in diesen Bereich tatsächlich aus der Datei liest und in diese schreibt. Wenn Sie eine Datei öffnen, dem Speicher zuordnen, in sie schreiben und speichern, wird die Änderung an der Datei auf der Festplatte vorgenommen (wenn sie sich natürlich auf einer Festplatte befindet).
Dies kann beispielsweise verwendet werden , wenn Sie wissen , Sie haben eine Menge von Zugriffen auf eine Datei zu tun, die nicht sequentiell sein würde, sein weil es einfacher und effizienter sein kann , zu tun Lese- und Schreibvorgänge im Speicher als zu Ausgabe
read
,write
, undllseek
Systemaufrufe. Das einzige Problem bei dieser Methode ist, dass Sie sie nicht wirklich verwenden können, wenn die Datei von mehreren Prozessen gleichzeitig gelesen oder beschrieben werden muss. Die Ergebnisse wären unvorhersehbar.Ich kenne keinen Befehl, der Ihnen sagen kann, ob eine Datei gerade zugeordnet ist. Sie können jedoch die Zuordnungen eines Prozesses in überprüfen
/proc/<pid>/maps
(sofern Ihr System über diese verfügt).Um Ihre zweite Frage zu beantworten: Wenn Sie eine Datei öffnen, können die Prozesse, die sie geöffnet haben, sie auch dann verwenden, wenn Sie sie in das Dateisystem verschieben. Was passiert ist, dass eine Datei nicht von ihren Einträgen in den Dateisystemen abhängig ist. Solange Sie eine Datei geöffnet haben, haben Sie ein "Handle", einen Dateideskriptor, mit dem Sie lesen und darauf schreiben können, selbst wenn sich der Pfad im Dateisystem ändert. Eine Datei verschwindet nur, wenn sie keinen Eintrag im Dateisystem hat und kein Prozess einen Dateideskriptor enthält.
quelle
/proc/<pid>/maps
. - Vorausgesetzt, dieser Prozess lebt auf einem System, das zunächst einen hat/proc
. OpenBSD tut dies nicht und FreeBSD läuft aus. Auch FreeBSD hat/proc/<pid>/map
statt/proc/<pid>/maps
.Der
lsof
Befehl zeigt Ihnen alle Dateien an, die derzeit vom System verwendet werden. Die Spalte "FD" enthält "mem", wenn der Datei Speicher zugeordnet ist. Sie können also die Ausgabe dieses Befehls nach dem Dateinamen durchsuchen, an dem Sie interessiert sind.quelle
lsof -ad mem /path/to/file
lsof -ad mem,txt /path/to/file
da Dateien, die ausgeführt werden, auch Teile davon im Prozessadressraum mmap haben, aber wietxt
in derlsof
Ausgabe erscheinen.Sie scheinen die Speicherzuordnung mit Dateien in speicherresidenten Dateisystemen zu verwechseln, zusammen mit anderen Konzepten wie der Art und Weise, wie Prozesse den Zugriff auf Dateien aufrechterhalten, selbst wenn diese verschoben werden.
Ich werde Frage für Frage gehen, um zu sehen, ob ich die Dinge klären kann.
Es verweist auf den Hauptspeicher, wenn es sich in einem speicherresidenten Dateisystem befindet, z. B. procfs, das normalerweise auf / proc gemountet ist, oder sysfs, das auf / sys ist, oder tmpfs, das manchmal auf / tmp ist.
Nein. Wie stephen-kitt sagte, bezieht sich "Speicherzuordnung" auf eine Möglichkeit, auf eine Datei zuzugreifen, indem sie im Hauptspeicher "zugeordnet" und dort damit gearbeitet wird, anstatt Blöcke gleichzeitig über Funktionen wie read () und zu lesen und zu schreiben schreiben().
Wenn Sie es innerhalb desselben Dateisystems verschieben, verschieben Sie wirklich nur eine Referenz, einen Inode von einem Verzeichnis in ein anderes. Wenn es Programme gibt, bei denen diese Datei bereits geöffnet wurde, greifen sie weiterhin auf dieselbe Datei zu, da sie den Inode bereits über einen Dateideskriptor zur Hand haben. Dies ist mit der Datei table_name.idb geschehen, die Sie in einem Kommentar erwähnt haben.
Wossname hat dies bereits für Dateien mit Speicherzuordnung beantwortet.
lsof
Hier erfahren Sie, welchen Prozessen die Datei im Speicher zugeordnet ist.Um festzustellen, ob sich eine Datei in einem speicherresidenten Dateisystem befindet, können Sie die Dateisysteme und ihre Mountpunkte verwenden
df
odermount
auflisten. Sie müssen nur wissen, welche Arten von Dateisystemen sich im Speicher befinden, indem Sie sie nachschlagen (z. B. in Wikipedia).Persönlich habe ich nicht die verwendetemmap
Funktion in einem C - Programm, aber wie ich es verstehe von Skimmingman mmap
undinfo mmap
gibt es keine Magie bei der Aufrechterhaltung der In-Memory beteiligt Darstellung synchron. In seiner Grundform kopiert der Aufruf von mmap den Dateiinhalt in den Speicher undmsync
wird verwendet, um ihn aus dem Speicher auf die Festplatte zurückzuschreiben. Wenn sich die Datei auf der Festplatte ändert, ist nichts vorhanden, um dies zu erkennen und die speicherinterne Darstellung in allen Prozessen, die sie zugeordnet haben, automatisch zu ändern.BEARBEITEN: Es stellt sich heraus, dass mmap () tatsächlich versucht, die speicherinterne Darstellung unter bestimmten Bedingungen synchron zu halten. Wenn die Karte nur gelesen wird, bleibt sie auch dann synchron, wenn andere Prozesse in die Datei schreiben. Wenn es geschrieben wird (durch Zuweisen zum Speicherbereich), hängt es davon ab, welches der anscheinend obligatorischen MAP_SHARED- oder MAP_PRIVATE-Flags für mmap () bereitgestellt wird. Wenn MAP_PRIVATE angegeben ist, wird die Map von der Darstellung auf der Festplatte getrennt und ist nicht mehr synchron, bis Sie msync () verwenden. Wenn MAP_SHARED bereitgestellt wird, werden die Aktualisierungen für andere Prozesse sichtbar gemacht, denen die Datei zugeordnet ist, sowie für die Darstellung auf der Festplatte (obwohl dies nicht unbedingt unmittelbar erforderlich ist).
Ich habe gerade vim für eine vorhandene Datei geöffnet
e
und den Befehl ausgeführt:w
, während ichinotifywait -m .
in einem anderen Terminal ausgeführt habe. Unter einigen seltsamen Dingen ist dies der wichtige Teil, von dem ich bekommen habeinotifywait
.Vim erstellt eine neue Datei und entfernt die alte. Warum dies geschieht, anstatt die Datei zu ändern, geht über den Rahmen dieser Frage hinaus, aber der Punkt ist, dass dies eine neue Datei ist und daher einen neuen Inode hat.
Was meinen Sie nun mit anderen Prozessen, die diese Datei verwenden? Wenn Sie Prozesse meinen, bei denen die Datei währenddessen geöffnet wurde, werden die Änderungen nicht angezeigt. Dies liegt daran, dass sie zwar eine Datei mit demselben Pfad geöffnet haben, jedoch nicht dieselbe Datei. Wenn Sie Prozesse meinen, die die Datei danach möglicherweise öffnen, werden die Änderungen angezeigt. Sie öffnen die neue Datei, die Sie erstellt haben.
Es ist wichtig zu beachten, dass Programme zwar eine Datei auf der Benutzeroberfläche geöffnet zu haben scheinen, dies jedoch nicht unbedingt bedeutet, dass sie die Datei dabei offen halten. Vim ist ein Beispiel dafür, wie oben gezeigt.
quelle
write
Funktion besteht darin, die Dateidaten zu ändern. Das kann bedeuten, dass der Inhalt auf der Festplatte geändert wird oder nicht, aber was auch immer es beinhaltet, es liegt in der Verantwortung des Dateisystems, es richtig zu machen. In diesem Fall müsste die zugeordnete Speicherseite geändert und als verschmutzt markiert werden.