Speicherzugeordnete Dateien können verwendet werden, um entweder den Lese- / Schreibzugriff zu ersetzen oder die gleichzeitige Freigabe zu unterstützen. Wenn Sie sie für einen Mechanismus verwenden, erhalten Sie auch den anderen.
Anstatt in einer Datei zu suchen, zu schreiben und zu lesen, ordnen Sie sie dem Speicher zu und greifen einfach auf die Bits zu, von denen Sie erwarten, dass sie sich befinden.
Dies kann sehr praktisch sein und je nach Schnittstelle des virtuellen Speichers die Leistung verbessern. Die Leistungsverbesserung kann auftreten, weil das Betriebssystem nun diese frühere "Datei-E / A" zusammen mit all Ihren anderen programmgesteuerten Speicherzugriffen verwalten kann und (theoretisch) die Paging-Algorithmen usw. nutzen kann, die es bereits zur Unterstützung verwendet virtueller Speicher für den Rest Ihres Programms. Dies hängt jedoch von der Qualität Ihres zugrunde liegenden virtuellen Speichersystems ab. Anekdoten Ich habe gehört, dass die virtuellen Speichersysteme Solaris und * BSD möglicherweise bessere Leistungsverbesserungen aufweisen als das VM-System von Linux - aber ich habe keine empirischen Daten, um dies zu belegen. YMMV.
Parallelität kommt ins Spiel, wenn Sie die Möglichkeit in Betracht ziehen, dass mehrere Prozesse dieselbe "Datei" über den zugeordneten Speicher verwenden. Wenn im Lese- / Schreibmodell zwei Prozesse in denselben Bereich der Datei schreiben, können Sie ziemlich sicher sein, dass eine der Prozessdaten in der Datei ankommt und die Daten des anderen Prozesses überschreibt. Du würdest das eine oder das andere bekommen - aber keine seltsame Vermischung. Ich muss zugeben, dass ich nicht sicher bin, ob dies ein Verhalten ist, das von einem Standard vorgeschrieben wird, aber darauf können Sie sich so ziemlich verlassen. (Es ist eigentlich eine gute Folgefrage!)
Stellen Sie sich im Gegensatz dazu in der kartierten Welt zwei Prozesse vor, die beide "schreiben". Sie tun dies, indem sie "Speicher" speichern, was dazu führt, dass der O / S die Daten auf die Festplatte auslagert - schließlich. In der Zwischenzeit ist jedoch mit überlappenden Schreibvorgängen zu rechnen.
Hier ist ein Beispiel. Angenommen, ich habe zwei Prozesse, die beide 8 Bytes am Offset 1024 schreiben. Prozess 1 schreibt '11111111' und Prozess 2 schreibt '22222222'. Wenn sie Datei-E / A verwenden, können Sie sich vorstellen, dass sich tief im Betriebssystem ein Puffer voller 1s und ein Puffer voller 2s befinden, die beide an dieselbe Stelle auf der Festplatte geleitet werden. Einer von ihnen wird zuerst dort ankommen und der andere eine Sekunde. In diesem Fall gewinnt der zweite. Allerdings , wenn ich die Memory-Mapped - Datei Ansatz verwende, Verfahren 1 wird eine Speicherspeicher von 4 Bytes gehen, durch einen anderen Speicher Speicher von 4 Bytes gefolgt (nehmen wir an , that't die maximale Speicherspeichergröße). Prozess 2 wird dasselbe tun. Abhängig davon, wann die Prozesse ausgeführt werden, können Sie Folgendes erwarten:
11111111
22222222
11112222
22221111
Die Lösung hierfür ist der explizite gegenseitige Ausschluss - was wahrscheinlich auf jeden Fall eine gute Idee ist. Sie haben sich sowieso darauf verlassen, dass das Betriebssystem "das Richtige" im E / A-Fall der Lese- / Schreibdatei tut.
Das Grundelement der gegenseitigen Ausgrenzung ist der Mutex. Für speicherabgebildete Dateien würde ich vorschlagen, dass Sie sich einen speicherabgebildeten Mutex ansehen, der mit (z. B.) pthread_mutex_init () verfügbar ist.
Bearbeiten mit einem Punkt: Wenn Sie zugeordnete Dateien verwenden, besteht die Versuchung, Zeiger auf die Daten in die Datei in die Datei selbst einzubetten (denken Sie an die in der zugeordneten Datei gespeicherte verknüpfte Liste). Sie möchten dies nicht tun, da die Datei möglicherweise zu unterschiedlichen Zeiten oder in unterschiedlichen Prozessen an unterschiedlichen absoluten Adressen zugeordnet wird. Verwenden Sie stattdessen Offsets in der zugeordneten Datei.