Ein Schreibvorgang unter der Größe von 'PIPE_BUF' soll atomar sein. Das sollten mindestens 512 Bytes sein, obwohl es leicht größer sein könnte (Linux scheint es auf 4096 gesetzt zu haben).
Dies setzt voraus, dass Sie alle vollständig POSIX-kompatiblen Komponenten sprechen. Dies gilt beispielsweise nicht für NFS.
Angenommen, Sie schreiben in eine Protokolldatei, die Sie im Modus 'O_APPEND' geöffnet haben, und halten Ihre Zeilen (einschließlich Zeilenumbruch) unter 'PIPE_BUF'-Bytes lang, sollten Sie in der Lage sein, mehrere Schreiber in eine Protokolldatei ohne Beschädigungsprobleme zu haben. Alle Interrupts kommen vor oder nach dem Schreiben an, nicht in der Mitte. Wenn Sie möchten, dass die Dateiintegrität einen Neustart überlebt, müssen Sie auch fsync(2)
nach jedem Schreibvorgang aufrufen , aber das ist für die Leistung schrecklich.
Klarstellung : Lesen Sie die Kommentare und die Antwort von Oz Solomon . Ich bin mir nicht sicher, ob das O_APPEND
diese PIPE_BUF
Größe Atomizität haben soll. Es ist durchaus möglich, dass Linux genau so implementiert ist write()
, oder es liegt an den Blockgrößen des zugrunde liegenden Dateisystems.
fsync(2)
eine ebenso große Garantie wie dies dersync(2)
Fall ist und hat weniger Auswirkungen auf die Leistung.PIPE_BUF
auf dieser Seite nur für Pipes und FIFOs, nicht für reguläre Dateien.Bearbeiten: Aktualisiert im August 2017 mit den neuesten Windows-Ergebnissen.
Ich werde Ihnen eine Antwort mit Links zu Testcode und Ergebnissen als Autor des Vorschlags geben Testcode Boost.AFIO geben, das ein asynchrones Dateisystem und eine Datei-I / O-C ++ - Bibliothek implementiert.
Erstens bedeutet O_APPEND oder das entsprechende FILE_APPEND_DATA unter Windows, dass Inkremente des maximalen Dateibereichs (Dateilänge) bei gleichzeitigen Writern atomar sind . Dies wird von POSIX garantiert und von Linux, FreeBSD, OS X und Windows korrekt implementiert. Samba implementiert es auch korrekt, NFS vor v5 nicht, da es nicht in der Lage ist, das Drahtformat atomar anzuhängen. Wenn Sie Ihre Datei also nur mit Anhängen öffnen, werden gleichzeitige Schreibvorgänge auf keinem größeren Betriebssystem in Bezug aufeinander gerissen, es sei denn, NFS ist beteiligt.
Gleichzeitige Lesevorgänge an atomaren Anhängen können jedoch möglich sein je nach Betriebssystem, Dateisystem und den Flags, mit denen Sie die Datei geöffnet haben, zerrissene Schreibvorgänge auftreten. Das Inkrement des maximalen Dateibereichs ist atomar, aber die Sichtbarkeit der Schreibvorgänge in Bezug auf Lesevorgänge kann oder kann nicht atomar sein. Hier ist eine kurze Zusammenfassung nach Flags, Betriebssystem und Dateisystem:
Nein O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 mit NTFS: Update Atomicity = 1 Byte bis einschließlich 10.0.10240, von 10.0.14393 mindestens 1 MB, wahrscheinlich unendlich (*).
Linux 4.2.6 mit ext4: Atomizität aktualisieren = 1 Byte
FreeBSD 10.2 mit ZFS: Atomizität aktualisieren = mindestens 1 MB, wahrscheinlich unendlich (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 mit NTFS: Aktualisieren Sie Atomicity = bis einschließlich 10.0.10240 bis zu 4096 Byte nur, wenn die Seite ausgerichtet ist, andernfalls 512 Byte, wenn FILE_FLAG_WRITE_THROUGH deaktiviert ist, andernfalls 64 Byte. Beachten Sie, dass diese Atomizität wahrscheinlich eher ein Merkmal von PCIe DMA ist als in. Seit 10.0.14393, mindestens 1 MB, wahrscheinlich unendlich (*).
Linux 4.2.6 mit ext4: Atomizität aktualisieren = mindestens 1 MB, wahrscheinlich unendlich (*). Beachten Sie, dass frühere Linuxes mit ext4 definitiv 4096 Bytes nicht überschritten haben. XFS hatte sicherlich benutzerdefinierte Sperren, aber es sieht so aus, als ob das aktuelle Linux dies endlich behoben hat.
FreeBSD 10.2 mit ZFS: Atomizität aktualisieren = mindestens 1 MB, wahrscheinlich unendlich (*)
Die rohen empirischen Testergebnisse finden Sie unter https://github.com/ned14/afio/tree/master/programs/fs-probe . Beachten Sie, dass wir nur bei 512-Byte-Vielfachen auf zerrissene Offsets testen. Daher kann ich nicht sagen, ob eine teilweise Aktualisierung eines 512-Byte-Sektors während des Lese-, Änderungs- und Schreibzyklus reißen würde.
Um die Frage des OP zu beantworten, stören sich O_APPEND-Schreibvorgänge nicht gegenseitig. Bei Lesevorgängen, die gleichzeitig mit O_APPEND-Schreibvorgängen ausgeführt werden, werden unter Linux mit ext4 wahrscheinlich zerrissene Schreibvorgänge angezeigt, es sei denn, O_DIRECT ist aktiviert, woraufhin Ihre O_APPEND-Schreibvorgänge ein Sektorgrößenmultiplikator sein müssten.
(*) "Wahrscheinlich unendlich" ergibt sich aus diesen Klauseln in der POSIX-Spezifikation:
und
aber umgekehrt:
Sie können mehr über die Bedeutung dieser in dieser Antwort lesen
quelle
Ich habe ein Skript geschrieben, um die maximale Größe der atomaren Anhänge empirisch zu testen. Das in bash geschriebene Skript erzeugt mehrere Arbeitsprozesse, die alle arbeiterspezifische Signaturen in dieselbe Datei schreiben. Anschließend wird die Datei gelesen und nach überlappenden oder beschädigten Signaturen gesucht. Sie können die Quelle für das Skript in diesem Blog-Beitrag sehen .
Die tatsächliche maximale Größe der atomaren Anhänge variiert nicht nur nach Betriebssystem, sondern auch nach Dateisystem.
Unter Linux + ext3 beträgt die Größe 4096 und unter Windows + NTFS 1024. Weitere Größen finden Sie in den Kommentaren unten.
quelle
echo $line >> $OUTPUT_FILE
einem einzigen Aufrufwrite
von führt$line
.Der Standard sagt Folgendes: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html .
quelle