Ich möchte mmap verwenden, um die Persistenz bestimmter Teile des Programmstatus in einem C-Programm zu implementieren, das unter Linux ausgeführt wird, indem ich eine Struktur mit fester Größe mit einem bekannten Dateinamen unter Verwendung von mmap() mit gesetztem MAP_SHARED-Flag verknüpfe. Aus Leistungsgründen würde ich es vorziehen, msync() überhaupt nicht aufzurufen, und keine anderen Programme werden auf diese Datei zugreifen. Wenn mein Programm beendet und neu gestartet wird, ordnet es dieselbe Datei erneut zu und verarbeitet sie, um den Zustand wiederherzustellen, in dem es sich vor der Beendigung befand. Meine Frage lautet: Wenn ich niemals msync() für den Dateideskriptor aufrufe, garantiert der Kernel, dass alle Aktualisierungen des Speichers auf die Festplatte geschrieben werden und anschließend wiederherstellbar sind, selbst wenn mein Prozess mit SIGKILL beendet wird? Wird es außerdem einen allgemeinen System-Overhead geben, da der Kernel regelmäßig die Seiten auf die Festplatte schreibt, selbst wenn mein Programm nie msync() aufruft?
BEARBEITEN: Ich habe das Problem gelöst, ob die Daten geschrieben werden, aber ich bin mir immer noch nicht sicher, ob dies zu einem unerwarteten Systemladen führen wird, wenn ich versuche, dieses Problem mit open()/write()/fsync() zu lösen und die Risiko, dass einige Daten verloren gehen könnten, wenn der Prozess von KILL/SEGV/ABRT/etc. getroffen wird. Ein ‘linux-kernel’-Tag hinzugefügt, in der Hoffnung, dass sich eine sachkundige Person melden könnte.
Die abgebildeten Seiten sind Teil des Dateisystem-Cache, was bedeutet, dass selbst wenn der Benutzerprozess, der eine Änderung an dieser Seite vorgenommen hat, stirbt, die Seite immer noch vom Kernel verwaltet wird und alle gleichzeitigen Zugriffe auf diese Datei durch den Kernel gehen, andere Prozesse werden aus diesem Cache bedient. In manchen alten Linux-Kerneln war das anders, deshalb wird in manchen Kernel-Dokumenten immer noch von force gesprochen msync.
EDIT: Danke RobH hat den Link korrigiert.
BEARBEITEN:
Seit Linux 4.15 wird ein neues Flag, MAP_SYNC, eingeführt, das die Kohärenz gewährleisten kann.
Shared-File-Mappings mit diesem Flag stellen sicher, dass ein Teil des Speichers zwar schreibbar im Adressraum des Prozesses abgebildet wird, aber in derselben Datei am selben Offset sichtbar ist, selbst nachdem das System abstürzt oder neu gestartet wird.
Beachten Sie, dass gemäß POSIX msync hat nichts mit dieser alten Linux-Anforderung zu tun, um sicherzustellen, dass Daten vor dem Aufheben/Beenden gespeichert werden. Es ist rein analog zu fsync und für Dinge wie die Verwaltung der Datenintegrität im Falle eines Hardware-/Stromausfalls gedacht (und, wenn ich mich erinnere, Aktualisierungen der Dateiänderungszeit).
– R.. GitHub HÖR AUF, EIS ZU HELFEN
27. September 2011 um 23:55 Uhr
Dieser Link kann alt sein. Dies ist eine direkte Verknüpfung zum (meiner Meinung nach) relevantesten Kommentar:
– RobH
14. März 2013 um 8:14 Uhr
Ich beschloss, weniger faul zu sein und die Frage, ob die Daten auf die Festplatte geschrieben werden, endgültig zu beantworten, indem ich etwas Code schrieb. Die Antwort ist, dass es geschrieben wird.
Hier ist ein Programm, das sich abrupt beendet, nachdem es einige Daten in eine mmap-Datei geschrieben hat:
Nun, streng genommen beweist ein Testprogramm allein nicht, dass das zuverlässig funktioniert. Daher sollte man sich stattdessen auf eine maßgebliche Spezifikation/Dokumentation/Erklärung verlassen.
– maxschlepzig
28. Oktober 2018 um 11:31 Uhr
zach
Ich habe etwas gefunden, das zu meiner Verwirrung beiträgt:
munmap wirkt sich nicht auf das zugeordnete Objekt aus, das heißt, Der Aufruf von munmap bewirkt nicht, dass der Inhalt der abgebildeten Region in die Plattendatei geschrieben wird. Die Aktualisierung der Festplattendatei für eine MAP_SHARED-Region erfolgt automatisch durch den virtuellen Speicheralgorithmus des Kernels, wenn wir in der speicherabgebildeten Region speichern.
hieraus ist ein Auszug Fortgeschrittene Programmierung in der UNIX®-Umgebung.
aus der Linux-Manpage:
MAP_SHARED Teilen Sie diese Zuordnung mit allen anderen Prozessen, die dieses Objekt abbilden. Das Speichern in der Region entspricht dem Schreiben in die Datei. Die Datei wird möglicherweise erst aktualisiert, wenn msync(2) oder munmap(2) aufgerufen werden.
die beiden scheinen widersprüchlich. ist APUE falsch?
Ich las den Kernel-Code über munmap versucht herauszufinden, wann und wie ist munmap Schreiben Sie den Cache zurück in die Datei. Aber aus dem Code wurde nichts gefunden. Also habe ich mich gefragt, ob es von etwas anderem gemacht wird, also denke ich, dass APUE Recht hat.
– John Zeng
27. Dezember 2016 um 6:43 Uhr
Ich habe keine sehr genaue Antwort auf Ihre Frage gefunden, also habe ich beschlossen, eine weitere hinzuzufügen:
Erstens über den Verlust von Daten, die Verwendung von Schreib- oder mmap/memcpy-Mechanismen schreibt sowohl in den Seitencache als auch wird vom Betriebssystem basierend auf seinen Seitenersetzungseinstellungen/-algos im Hintergrund mit dem zugrunde liegenden Speicher synchronisiert. Zum Beispiel hat Linux vm.dirty_writeback_centisecs, das bestimmt, welche Seiten als “alt” gelten und auf die Festplatte geleert werden. Selbst wenn Ihr Prozess nach erfolgreichem Schreibaufruf abbricht, gehen die Daten nicht verloren, da die Daten bereits in Kernelseiten vorhanden sind, die schließlich in den Speicher geschrieben werden. Der einzige Fall, in dem Sie Daten verlieren würden, ist, wenn das Betriebssystem selbst abstürzt (Kernelpanik, Ausschalten usw.). Der Weg, um absolut sicherzustellen, dass Ihre Daten den Speicher erreicht haben, wäre der Aufruf von fsync oder msync (für mmappte Regionen), je nach Fall.
Was die Systemlast betrifft, ja, das Aufrufen von msync/fsync für jede Anfrage wird Ihren Durchsatz drastisch verlangsamen, also tun Sie das nur, wenn Sie müssen. Denken Sie daran, dass Sie sich wirklich vor Datenverlust bei Betriebssystemabstürzen schützen, was meiner Meinung nach selten ist und wahrscheinlich etwas, mit dem die meisten leben könnten. Eine allgemeine Optimierung besteht darin, in regelmäßigen Abständen, z. B. 1 Sekunde, eine Synchronisierung durchzuführen, um eine gute Balance zu erhalten.
Entweder sind die Informationen auf der Linux-Manpage falsch oder Linux ist schrecklich nicht konform. msync soll nichts damit zu tun haben, ob die Änderungen auf den logischen Zustand der Datei übertragen werden oder ob andere Prozesse dies verwenden mmap oder read um auf die Datei zuzugreifen, sehen Sie sich die Änderungen an; es ist ein reines Analogon von fsync und sollte als No-Op behandelt werden, außer um die Datenintegrität im Falle eines Stromausfalls oder eines anderen Ausfalls auf Hardwareebene sicherzustellen.
Nun, munmap (oder besser gesagt die entsprechende Funktion des Kernels flush_whatsitcalled) wird in beiden Fällen aufgerufen, wenn der Prozess beendet wird, also gibt es nicht wirklich ein Problem, oder? Es wäre verheerend, wenn Mappings nicht auf die Festplatte geschrieben würden, wenn ein Prozess stirbt, denn nicht wenige Programme (darunter einige, die ich geschrieben habe) verlassen sich darauf.
– Dämon
5. Mai 2011 um 22:19 Uhr
Beachten Sie auch, dass die freigegebenen Seiten von zugeordnet werden mmap werden mit dem Dateisystem-Cache geteilt, daher sehe ich keine Möglichkeit, dass es zu Inkonsistenzen oder Datenverlust kommen könnte. Ich denke, es würde eine absichtlich kaputte Implementierung erfordern, um Daten zu verlieren (wofür uClinux/NOMMU ein Beispiel ist :).
– R.. GitHub HÖR AUF, EIS ZU HELFEN
5. Mai 2011 um 22:26 Uhr
John Ledbetter
Laut Manpage,
Die Datei wird möglicherweise erst aktualisiert, wenn msync(2) oder munmap() aufgerufen wird.
Sie müssen also sicherstellen, dass Sie anrufen munmap() zumindest vor dem Ausstieg.
Nun, munmap (oder besser gesagt die entsprechende Funktion des Kernels flush_whatsitcalled) wird in beiden Fällen aufgerufen, wenn der Prozess beendet wird, also gibt es nicht wirklich ein Problem, oder? Es wäre verheerend, wenn Mappings nicht auf die Festplatte geschrieben würden, wenn ein Prozess stirbt, denn nicht wenige Programme (darunter einige, die ich geschrieben habe) verlassen sich darauf.
– Dämon
5. Mai 2011 um 22:19 Uhr
Beachten Sie auch, dass die freigegebenen Seiten von zugeordnet werden mmap werden mit dem Dateisystem-Cache geteilt, daher sehe ich keine Möglichkeit, dass es zu Inkonsistenzen oder Datenverlust kommen könnte. Ich denke, es würde eine absichtlich kaputte Implementierung erfordern, um Daten zu verlieren (wofür uClinux/NOMMU ein Beispiel ist :).
– R.. GitHub HÖR AUF, EIS ZU HELFEN
5. Mai 2011 um 22:26 Uhr
13802500cookie-checkmmap-, msync- und Linux-Prozessbeendigungyes