Ist die Datei atomar in UNIX?
In der Regel, was können wir für selbstverständlich halten, wenn wir uns Anhängen, um eine Datei in UNIX mehrere Prozesse? Ist es möglich, Daten zu verlieren (ein Prozess überschreiben der änderungen von anderen)? Ist es möglich, Daten zu erhalten, entstellt sind? (Zum Beispiel, jeder Prozess Anhängen einer Zeile per "anfügen", um eine log-Datei, ist es möglich, dass zwei Linien zu bekommen entstellte?) Wenn der append-ist nicht atomar im obigen Sinne, was ist dann der beste Weg, um wechselseitigen Ausschluss?
InformationsquelleAutor der Frage Lajos Nagy | 2009-07-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einem schreiben, das unter die Größe von 'PIPE_BUF' sein soll, atomic. Das sollte mindestens 512 bytes, obwohl es könnte leicht größer sein (linux scheint es auf 4096 gesetzt).
Diese davon ausgehen, dass Sie reden alle voll POSIX-konforme Komponenten. Zum Beispiel, das ist nicht wahr auf NFS.
Aber vorausgesetzt, Sie schreiben in eine log-Datei, die Sie geöffnet in 'O_APPEND" - Modus und halten Sie Ihre Linien (einschließlich newline) unter 'PIPE_BUF' bytes lang ist, sollten Sie in der Lage, mehrere Autoren zu einer log-Datei, ohne irgendwelche Fragen der Korruption. Keine interrupts kommen vor oder nach dem schreiben, nicht in der Mitte. Wenn Sie möchten, dass die Integrität der Datei, um zu überleben einen Neustart wirst du auch benötigen, rufen Sie
fsync(2)
nach jeder schreiben, aber das ist schrecklich für die Leistung.Klärung: Lesen Sie die Kommentare und Oz Solomon ' s Antwort. Ich bin mir nicht sicher, dass
O_APPEND
haben soll, dassPIPE_BUF
Größe Unteilbarkeit. Es ist durchaus möglich, dass es genau wie Linux implementiertwrite()
ist, oder es kann aufgrund der zugrunde liegenden Dateisystem, block-Größen.InformationsquelleAutor der Antwort freiheit
Edit: Aktualisiert August 2017 mit der neuesten Windows-Ergebnisse.
Werde ich Ihnen eine Antwort geben mit links zu test-code und die Ergebnisse, wie der Autor vorgeschlagenen Boost.AFIO die implementiert eine asynchrone filesystem-und Datei-i/o C++ - Bibliothek.
Erstens, O_APPEND oder den Gegenwert FILE_APPEND_DATA auf Windows bedeutet, dass die Inkremente der maximalen Datei-Umfang (Datei "Länge") sind atomic unter gleichzeitiger Schriftsteller. Dies wird garantiert durch POSIX und Linux, FreeBSD, OS X und Windows alle umsetzen richtig. Samba implementiert auch richtig, NFS, bevor v5 nicht, denn es fehlt der Draht-format-Fähigkeit zum Anhängen atomar. Also, wenn Sie öffnen Sie Ihre Datei mit dem append-only, gleichzeitige schreibt, wird nicht reißen, mit gegenseitigen Respekt auf allen gängigen OSes sei denn, NFS beteiligt ist.
Jedoch die gleichzeitige liest atomic hängt kann sehen zerrissene Schreibvorgänge je nach OS, filing-system, und welche Fahnen Sie öffnete die Datei mit - der Zuwachs der maximale Datei-Umfang ist atomar, aber die Sichtbarkeit der schreibt mit Bezug auf liest werden können oder nicht atomar. Hier ist eine kurze Zusammenfassung von Fahnen, OS und Dateisystem:
Keine O_DIRECT/FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 mit NTFS: update Atomarität = 1 byte bis einschließlich 10.0.10240, von 10.0.14393 mindestens 1Mb, wahrscheinlich unendlich (*).
Linux 4.2.6 mit ext4: update Atomarität = 1 byte
FreeBSD 10.2 mit ZFS: update Atomarität = mindestens 1Mb, wahrscheinlich unendlich (*)
O_DIRECT/FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 mit NTFS: update Atomarität = bis einschließlich 10.0.10240 bis zu 4096 bytes nur wenn Seite ausgerichtet, sonst 512 bytes, wenn FILE_FLAG_WRITE_THROUGH-off, sonst 64 bytes. Beachten Sie, dass diese Unteilbarkeit ist wohl ein feature von PCIe-DMA-statt gestaltet. Da 10.0.14393, mindestens 1Mb, wahrscheinlich unendlich (*).
Linux 4.2.6 mit ext4: update Atomarität = mindestens 1Mb, wahrscheinlich unendlich (*). Beachten Sie, dass in früheren Linux-Versionen mit ext4 definitiv nicht mehr als 4096 bytes, XFS sicherlich verwendet, um benutzerdefinierte sperren, aber es sieht aus wie aktuelle Linux hat, ist endlich behoben.
FreeBSD 10.2 mit ZFS: update Atomarität = mindestens 1Mb, wahrscheinlich unendlich (*)
Sehen Sie die raw-empirische Untersuchungsergebnisse im https://github.com/ned14/afio/tree/master/programs/fs-probe. Hinweis: wir testen für gerissene offsets nur auf 512 byte gruppiert, so kann ich nicht sagen, wenn einem teilweisen update einer 512-byte-Sektor reißen würde, während die read-modify-write-Zyklus.
So, die Antwort auf die OP-Frage, O_APPEND schreibt nicht gegenseitig stören, aber liest zeitgleich zu O_APPEND schreibt, wird wahrscheinlich sehen, zerrissene Schreibvorgänge auf Linux mit ext4, es sei denn, O_DIRECT ist, worauf Ihr O_APPEND schreibt brauchen würde, um eine Sektor-Größe mehrere.
(*) "Wahrscheinlich unendlich" ergibt sich aus diesen Klauseln in der POSIX-Spezifikation:
und
aber Umgekehrt:
Lesen Sie mehr über die Bedeutung dieser in dieser Antwort
InformationsquelleAutor der Antwort Niall Douglas
Schrieb ich ein Skript, um empirisch zu testen, die maximale Atomare Größe Anhängen. Das Skript, geschrieben in bash, laicht mehrere worker-Prozesse, die alle schreiben, dass die Arbeiter-spezifische Signaturen für die gleiche Datei. Es liest dann die Datei, auf der Suche nach überlappenden oder beschädigten Signaturen. Sehen Sie die Quelle für das Skript an dieser blog-post.
Die tatsächliche maximale atomic append-Größe variiert nicht nur vom OS, sondern vom Dateisystem.
Unter Linux+ext3 die Größe ist 4096, und auf Windows+NTFS-Größe ist 1024. Siehe die Kommentare unten für weitere Größen.
InformationsquelleAutor der Antwort Oz Solomon
Hier ist, was der standard sagt: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html.
InformationsquelleAutor der Antwort Bastien Léonard