Se supone que una escritura cuyo tamaño es inferior a 'PIPE_BUF' es atómica. Eso debería ser de al menos 512 bytes, aunque fácilmente podría ser más grande (Linux parece tenerlo configurado en 4096).
Esto supone que está hablando de todos los componentes totalmente compatibles con POSIX. Por ejemplo, esto no es cierto en NFS.
Pero asumiendo que escribe en un archivo de registro que abrió en el modo 'O_APPEND' y mantiene sus líneas (incluida la nueva línea) en bytes de 'PIPE_BUF', debería poder tener varios escritores en un archivo de registro sin problemas de corrupción. Cualquier interrupción llegará antes o después de la escritura, no en el medio. Si desea que la integridad del archivo sobreviva a un reinicio, también deberá llamarfsync(2)
después de cada escritura, pero eso es terrible para el rendimiento.
Aclaración : lea los comentarios y la respuesta de Oz Solomon . No estoy seguro de que O_APPEND
se suponga que tenga ese PIPE_BUF
tamaño de atomicidad. Es muy posible que sea así como se implementó Linux write()
, o puede deberse a los tamaños de bloque del sistema de archivos subyacente.
fsync(2)
ofrece tanta garantía como losync(2)
hace, y no tiene un impacto tan grande en el rendimiento.PIPE_BUF
en esa página solo se aplica a tuberías y FIFO, no a archivos normales.Editar: actualizado en agosto de 2017 con los últimos resultados de Windows.
Voy a darle una respuesta con enlaces para probar el código y los resultados como autor de la propuesta Boost.AFIO, que implementa un sistema de archivos asíncrono y una biblioteca de archivos de E / S C ++.
En primer lugar, O_APPEND o el equivalente FILE_APPEND_DATA en Windows significa que los incrementos de la extensión máxima del archivo ("longitud" del archivo) son atómicos en escritores simultáneos. Esto está garantizado por POSIX, y Linux, FreeBSD, OS X y Windows lo implementan correctamente. Samba también lo implementa correctamente, NFS antes de v5 no lo hace, ya que carece de la capacidad de formato de cable para anexar atómicamente. Entonces, si abre su archivo con solo agregar, las escrituras simultáneas no se romperán entre sí en ningún sistema operativo principal menos que NFS esté involucrado.
Sin embargo, las lecturas simultáneas de anexos atómicos pueden ver escrituras desgarradas según el sistema operativo, el sistema de archivo y los indicadores con los que abrió el archivo; el incremento de la extensión máxima del archivo es atómico, pero la visibilidad de las escrituras con respecto a las lecturas puede o no ser atómico. Aquí hay un resumen rápido por banderas, sistema operativo y sistema de archivo:
No O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 con NTFS: atomicidad de actualización = 1 byte hasta 10.0.10240 inclusive, desde 10.0.14393 al menos 1Mb, probablemente infinito (*).
Linux 4.2.6 con ext4: actualización de atomicidad = 1 byte
FreeBSD 10.2 con ZFS: actualizar la atomicidad = al menos 1 Mb, probablemente infinito (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 con NTFS: actualice la atomicidad = hasta 10.0.10240 inclusive hasta 4096 bytes solo si la página está alineada, de lo contrario, 512 bytes si FILE_FLAG_WRITE_THROUGH está desactivado, si no 64 bytes. Tenga en cuenta que esta atomicidad es probablemente una característica de PCIe DMA en lugar de estar diseñada. Desde 10.0.14393, al menos 1 Mb, probablemente infinito (*).
Linux 4.2.6 con ext4: actualizar la atomicidad = al menos 1 Mb, probablemente infinito (*). Tenga en cuenta que los Linux anteriores con ext4 definitivamente no excedían los 4096 bytes, XFS ciertamente solía tener un bloqueo personalizado, pero parece que el Linux reciente finalmente lo solucionó.
FreeBSD 10.2 con ZFS: actualizar la atomicidad = al menos 1 Mb, probablemente infinito (*)
Puede ver los resultados de las pruebas empíricas sin procesar en https://github.com/ned14/afio/tree/master/programs/fs-probe . Tenga en cuenta que probamos las compensaciones rotas solo en múltiplos de 512 bytes, por lo que no puedo decir si una actualización parcial de un sector de 512 bytes se rompería durante el ciclo de lectura-modificación-escritura.
Entonces, para responder a la pregunta del OP, las escrituras O_APPEND no interferirán entre sí, pero las lecturas simultáneas a las escrituras O_APPEND probablemente verán escrituras desgarradas en Linux con ext4 a menos que O_DIRECT esté activado, por lo que sus escrituras O_APPEND necesitarían ser un tamaño de sector múltiple.
(*) "Probablemente infinito" se deriva de estas cláusulas en la especificación POSIX:
y
pero a la inversa:
Puede leer más sobre el significado de estos en esta respuesta
fuente
Escribí un guión para probar empíricamente el tamaño máximo de anexo atómico. El script, escrito en bash, genera múltiples procesos de trabajo que escriben firmas específicas de trabajador en el mismo archivo. Luego lee el archivo en busca de firmas superpuestas o dañadas. Puede ver la fuente del script en esta publicación de blog .
El tamaño máximo real de los agregados atómicos varía no solo según el sistema operativo, sino también según el sistema de archivos.
En Linux + ext3 el tamaño es 4096 y en Windows + NTFS el tamaño es 1024. Consulte los comentarios a continuación para ver más tamaños.
fuente
echo $line >> $OUTPUT_FILE
resultará en una sola llamada awrite
independientemente del tamaño de$line
.Esto es lo que dice el estándar: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html .
fuente