Domanda

In generale, che cosa possiamo dare per scontato quando si aggiungere a un file in UNIX da più processi? E 'possibile perdita di dati (un processo di sovrascrivere della altri cambiamenti)? E 'possibile che i dati storpiati? (Per esempio, ogni processo è aggiungendo una linea per accodamento per un file di registro, è possibile che due linee storpiati?) Se l'accodamento non è atomica nel senso di cui sopra, quindi qual è il modo migliore per assicurare mutua esclusione?

È stato utile?

Soluzione

Una scrittura che è sotto la dimensione della 'PIPE_BUF' si suppone che sia atomica. Questo dovrebbe essere di almeno 512 byte, anche se potrebbe facilmente essere più grande (linux sembra avere impostato su 4096).

Questo presumere che si sta parlando di tutti i componenti completamente POSIX-compliant. Per esempio, questo non è vero in NFS.

Ma supponendo che si scrive in un file di log è stato aperto in modalità 'O_APPEND' e mantenere le linee (tra cui a capo) sotto byte 'PIPE_BUF' lungo, si dovrebbe essere in grado di avere più scrittori in un file di registro, senza problemi di corruzione. Eventuali interruzioni arriveranno prima o dopo la scrittura, non nel mezzo. Se si desidera archiviare l'integrità per sopravvivere un riavvio avrete anche bisogno di chiamare fsync(2) dopo ogni scrittura, ma questo è terribile per le prestazioni.

Chiarimento : leggere i commenti e di Oz Solomon risposta . Non sono sicuro che O_APPEND si suppone di avere che atomicità dimensioni PIPE_BUF. E 'del tutto possibile che si tratta solo di come Linux implementato write(), o può essere dovuto alla dimensione dei blocchi del filesystem sottostante.

Altri suggerimenti

Modifica:. Aggiornamento agosto 2017 con risultati più recenti di Windows

ho intenzione di dare una risposta con i link per testare il codice e risultati come l'autore di proposta di Boost.AFIO che implementa un file system asincrona e file di I / O libreria C ++.

In primo luogo, O_APPEND o FILE_APPEND_DATA equivalente su Windows significa che incrementi del file misura massima (file "lunghezza") sono atomica sotto gli scrittori contemporanei. Questo è garantito da POSIX, e Linux, FreeBSD, OS X e Windows tutto attuarla correttamente. Samba implementa anche correttamente, NFS prima v5 non costituisce in quanto manca la capacità filo formato da aggiungere atomicamente. Quindi, se si apre il file con append-only, scrive concorrenti saranno non strappare con uno rispetto all'altro su qualsiasi sistema operativo principale a meno che NFS è coinvolto.

Tuttavia concomitante si legge per accodamento atomiche possono vedere strappato scrive seconda del sistema operativo, sistema di archiviazione, e ciò che le bandiere si apre il file con - l'incremento della portata massima del file è atomica, ma la visibilità delle operazioni di scrittura rispetto alla legge può o non può essere atomica. Ecco un breve riassunto da bandiere, sistema operativo e sistema di archiviazione:


No O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 con NTFS:. Update atomicità = 1 byte fino e compreso 10.0.10240, dal 10.0.14393 almeno 1Mb, probabilmente infinita (*)

Linux 4.2.6 con ext4: aggiornamento atomicità = 1 byte

FreeBSD 10.2 con ZFS: aggiornamento atomicità = almeno 1Mb, probabilmente infinita (*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 con NTFS: aggiornamento atomicità = fino e compreso 10.0.10240 fino a 4096 byte solo se la pagina allineati, altrimenti 512 byte se FILE_FLAG_WRITE_THROUGH off, altro 64 byte. Si noti che questo atomicità è probabilmente una caratteristica di PCIe DMA piuttosto che progettata in. Dal 10.0.14393, almeno 1Mb, probabilmente infinita (*).

Linux 4.2.6 con ext4: aggiornamento atomicità = almeno 1Mb, probabilmente infinita (*). Si noti che versioni di Linux precedenti con ext4 sicuramente non ha superato 4096 byte, XFS certamente usato per avere personalizzato il blocco, ma sembra che di recente Linux è finalmente risolto questo.

FreeBSD 10.2 con ZFS: aggiornamento atomicità = almeno 1Mb, probabilmente infinita (*)


È possibile visualizzare i risultati del test empirici prime a https: // GitHub .com / ned14 / afio / albero / master / programmi / fs-probe . Notare che prova per offset strappati solo su 512 byte multipli, quindi non posso dire se un aggiornamento parziale di un settore di 512 byte strapperebbe durante il ciclo di lettura-modifica-scrittura.

Quindi, per rispondere alla domanda del PO, O_APPEND scrive non interferirà con l'un l'altro, ma legge concorrente a O_APPEND scrive probabilmente vedrete strappato scrive su Linux con ext4 a meno O_DIRECT è attiva, dopo di che i vostri scrive O_APPEND avrebbe bisogno di essere un settore formato multiplo.


(*) "Probabilmente infinita" nasce da queste clausole specifiche POSIX:

  

Tutte le seguenti funzioni sarà atomico rispetto ad ogni   altro in degli effetti previsti dal POSIX.1-2008 quando operano su   file regolari o collegamenti simbolici ... [molte funzioni] ... read () ...   scrittura () ... Se due thread ogni chiamata una di queste funzioni, ciascuna chiamata   si sia vedere tutti gli effetti di cui dell'altra chiamata o   nessuno di loro. [Fonte]

e

  

Scrive possono essere serializzati rispetto ad altre letture e scritture. Se una   read () dei dati dei file può essere provato (con qualsiasi mezzo) a verificarsi dopo un   scrivere () dei dati, si deve riflettere sul fatto che write (), anche se le chiamate   sono realizzati da diversi processi. [Fonte]

, ma al contrario:

  

Questo volume di POSIX.1-2008 non specifica il comportamento del concorrente   scrive in un file da più processi. Le applicazioni devono utilizzare alcuni   forma di controllo della concorrenza. [Fonte]

Si può leggere di più sul significato di questi in questa risposta

Ho scritto uno script per testare empiricamente la dimensione massima di accodamento atomica. La sceneggiatura, scritta in bash, genera più processi di lavoro che tutti Scrivi firme specifiche per lavoratori allo stesso file. E 'quindi legge il file, alla ricerca di firme sovrapposizioni o danneggiati. Si può vedere la fonte per lo script a questo post sul blog .

La dimensione effettiva massima accodamento atomica varia non solo da parte del sistema operativo, ma dal file system.

In Linux + ext3 la dimensione è 4096, e su Windows + NTFS la dimensione è 1024. Vedi le commenti qui sotto per più dimensioni.

Ecco cosa dice la norma: http://www.opengroup.org /onlinepubs/009695399/functions/pwrite.html .

  

Se viene impostato il flag O_APPEND dei flag di stato, il file di offset è fissato alla fine del file prima di ogni operazione di scrittura e nessuna operazione di modifica del file intervenendo avverrà tra modifica dello spostamento del file e l'operazione di scrittura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top