Modifica: aggiornato ad agosto 2017 con gli ultimi risultati di Windows.
Ti darò una risposta con collegamenti al codice di test e risultati come autore della proposta Boost.AFIO che implementa un filesystem asincrono e una libreria di file i / o C ++.
In primo luogo, O_APPEND o l'equivalente FILE_APPEND_DATA su Windows significa che gli incrementi dell'estensione massima del file ("lunghezza" del file) sono atomici con i writer simultanei. Questo è garantito da POSIX e Linux, FreeBSD, OS X e Windows lo implementano correttamente. Anche Samba lo implementa correttamente, NFS prima della v5 non lo fa in quanto manca della capacità di formato wire per essere aggiunto in modo atomico. Quindi, se apri il tuo file con solo aggiunta , le scritture simultanee non si interromperanno l'una rispetto all'altra su nessun sistema operativo principale a meno che non sia coinvolto NFS.
Tuttavia, le letture simultanee su aggiunte atomiche possono vedere scritture danneggiate a seconda del sistema operativo, del sistema di archiviazione e dei flag con cui hai aperto il file: l'incremento dell'estensione massima del file è atomico, ma la visibilità delle scritture rispetto alle letture può o meno essere atomico. Ecco un breve riepilogo per flag, sistema operativo e sistema di archiviazione:
No O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 con NTFS: aggiornamento atomicità = 1 byte fino a 10.0.10240 compreso, da 10.0.14393 almeno 1 Mb, probabilmente infinito (*).
Linux 4.2.6 con ext4: aggiornamento atomicità = 1 byte
FreeBSD 10.2 con ZFS: aggiornamento atomicità = almeno 1Mb, probabilmente infinito (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 con NTFS: aggiorna atomicity = fino a 10.0.10240 compreso fino a 4096 byte solo se pagina allineata, altrimenti 512 byte se FILE_FLAG_WRITE_THROUGH disattivato, altrimenti 64 byte. Si noti che questa atomicità è probabilmente una caratteristica del PCIe DMA piuttosto che progettata in. Dal 10.0.14393, almeno 1 Mb, probabilmente infinita (*).
Linux 4.2.6 con ext4: aggiornamento atomicità = almeno 1Mb, probabilmente infinito (*). Si noti che i precedenti Linux con ext4 non superavano sicuramente i 4096 byte, XFS sicuramente aveva un blocco personalizzato, ma sembra che Linux recente abbia finalmente risolto questo problema.
FreeBSD 10.2 con ZFS: aggiornamento atomicità = almeno 1Mb, probabilmente infinito (*)
Puoi vedere i risultati del test empirico grezzo su https://github.com/ned14/afio/tree/master/programs/fs-probe . Nota che testiamo gli offset strappati solo su multipli di 512 byte, quindi non posso dire se un aggiornamento parziale di un settore di 512 byte si interromperebbe durante il ciclo di lettura-modifica-scrittura.
Quindi, per rispondere alla domanda dell'OP, le scritture O_APPEND non interferiranno tra loro, ma le letture simultanee alle scritture O_APPEND probabilmente vedranno scritture strappate su Linux con ext4 a meno che O_DIRECT non sia attivo, dopodiché le tue scritture O_APPEND dovrebbero essere un multiplo di dimensioni di settore.
(*) "Probabilmente infinito" deriva da queste clausole nelle specifiche POSIX:
Tutte le seguenti funzioni devono essere atomiche l'una rispetto all'altra negli effetti specificati in POSIX.1-2008 quando operano su file regolari o collegamenti simbolici ... [molte funzioni] ... read () ... write ( ) ... Se due thread chiamano ciascuno una di queste funzioni, ogni chiamata vedrà tutti gli effetti specificati dell'altra chiamata o nessuno di essi. [Fonte]
e
Le scritture possono essere serializzate rispetto ad altre letture e scritture. Se è possibile dimostrare (con qualsiasi mezzo) che una read () dei dati di un file si verifica dopo una write () dei dati, deve riflettere tale write (), anche se le chiamate vengono effettuate da processi diversi. [Fonte]
ma al contrario:
Questo volume di POSIX.1-2008 non specifica il comportamento delle scritture simultanee su un file da più processi. Le applicazioni dovrebbero utilizzare una qualche forma di controllo della concorrenza. [Fonte]
Puoi leggere di più sul significato di questi in questa risposta
fsync(2)
offre la stessa garanzia chesync(2)
ha e non ha un impatto così grande sulle prestazioni.