Mit Speicherkarten verknüpfte Dateien können entweder den Lese-/Schreibzugriff ersetzen oder die gleichzeitige Freigabe unterstützen. Wenn Sie sie für einen Mechanismus verwenden, erhalten Sie auch den anderen.
Anstatt zu suchen und zu schreiben und in einer Datei zu lesen, ordnen Sie sie in den Speicher ein und greifen einfach auf die Bits zu, wo Sie sie erwarten.
Dies kann sehr praktisch sein, und abhängig von der virtuellen Speicherschnittstelle kann die Leistung verbessern. Die Leistungsverbesserung kann auftreten, weil das Betriebssystem jetzt diese frühere "Datei-I/O" zusammen mit all Ihren anderen programmatischen Speicherzugriffen verwaltet und (theoretisch) die Paging-Algorithmen usw. einsetzen kann, die es bereits zur Unterstützung verwendet virtueller Speicher für die Rest Ihres Programms. Es hängt jedoch von der Qualität Ihres zugrunde liegenden virtuellen Speichersystems ab. Anekdoten, die ich gehört habe, sagen, dass die Solaris und * BSD virtuellen Speichersysteme möglicherweise bessere Leistungsverbesserungen zeigen als das VM-System von Linux - aber ich habe keine empirischen Daten, um dies zu untermauern. YMMV.
Nebenläufigkeit kommt ins Bild, wenn Sie die Möglichkeit mehrerer Prozesse betrachten, die dieselbe "Datei" über zugeordneten Speicher verwenden. Wenn beim Lesen/Schreiben-Modell zwei Prozesse in denselben Bereich der Datei geschrieben werden, kann man ziemlich sicher sein, dass eine der Daten des Prozesses in der Datei eintrifft und die Daten des anderen Prozesses überschreibt. Du würdest den einen oder den anderen bekommen - aber nicht eine seltsame Vermischung. Ich muss zugeben, dass ich mir nicht sicher bin, ob dies ein Verhalten ist, das von irgendeinem Standard vorgeschrieben wird, aber darauf kann man sich ziemlich verlassen. (Es ist eigentlich eine gute Folge Frage!)
In der abgebildeten Welt, im Gegensatz, stellen Sie sich zwei Prozesse "Schreiben". Sie tun dies, indem sie "Speicherspeicher" ausführen, was dazu führt, dass das Betriebssystem die Daten auf die Festplatte auslagert - schließlich. In der Zwischenzeit kann jedoch mit überlappenden Schreibvorgängen gerechnet werden.
Hier ist ein Beispiel. Angenommen, ich habe zwei Prozesse, die jeweils 8 Bytes bei Offset 1024 schreiben. Prozess 1 schreibt '11111111' und Prozess 2 schreibt '22222222'. Wenn sie Datei-I/O benutzen, dann können Sie sich vorstellen, dass tief im O/S ein Puffer voll von 1s und ein Puffer voll von 2s ist, beide auf die gleiche Stelle auf der Platte geleitet. Einer von ihnen wird zuerst da sein, und der andere eine Sekunde. In diesem Fall gewinnt der zweite. Allerdings, wenn ich die Speicher-Mapped-Datei Ansatz verwenden, wird Prozess 1 gehen zu einem Speicher von 4 Bytes, gefolgt von einem anderen Speicher von 4 Bytes (nehmen wir an, dass nicht die maximale Speichergröße).Prozess 2 wird dasselbe tun. Basierend auf, wenn die Prozesse ausführen, können Sie eine der folgenden Aktionen zu erwarten:
11111111
22222222
11112222
22221111
Die Lösung hierfür ist ausdrücklich gegenseitigen Ausschluss verwenden - das ist wahrscheinlich eine gute Idee, auf jeden Fall ist. Sie waren irgendwie darauf angewiesen, dass das O/S das "Richtige" in dem E/A-Schreib-/Lese-Fall von Dateien sowieso macht.
Die Klasse wechselseitiges Ausschließen ist der Mutex. Für Speicher-Mapping-Dateien würde ich vorschlagen, dass Sie sich einen Speicher-gemappten Mutex ansehen, der unter Verwendung von (z. B.) pthread_mutex_init() verfügbar ist.
Bearbeiten mit einem Fehler: Wenn Sie zugeordnete Dateien verwenden, gibt es eine Versuchung, Zeiger auf die Daten in der Datei einzubetten, in der Datei selbst (denken Sie daran, verknüpfte Liste in der zugeordneten Datei gespeichert). Das möchten Sie nicht tun, da die Datei möglicherweise zu verschiedenen Zeiten oder in verschiedenen Prozessen unter verschiedenen absoluten Adressen abgebildet wird. Verwenden Sie stattdessen Offsets innerhalb der zugeordneten Datei.
Unter Windows mindestens können Sie mehrere 32bit Ansichten einer größeren mmap-Datei zuordnen - die effizienter sein kann als der Versuch, mit sehr großen Dateien mit regulären CRT-Funktion zu behandeln –
@MarkR Sie schrieb "seine zusätzliche Kopie braucht nicht nur Zeit , ** verringert jedoch die Effektivität der Caches der CPU durch Zugriff auf diese zusätzliche Kopie der Daten. ** ". (** Betonung ** meins). Können Sie bitte erklären, wie die zusätzliche Pufferkopie im Kernel die Effektivität der Caches der CPU verhindert? – Geek
@Geek Zugriff doppelt so viel Speicher = doppelt so viel Cache verschwendet (sehr ungefähr). – immibis