Pregunta

En general, ¿qué podemos dar por sentado cuando añadimos a un archivo en UNIX desde múltiples procesos? ¿Es posible perder datos (un proceso de sobrescribir los cambios del otro)? ¿Es posible que los datos a mezclarse o? (Por ejemplo, cada proceso se anexando una línea por anexados para un archivo de registro, es posible que dos líneas consiguen destrozado?) Si el append no es atómica en el sentido anterior, entonces ¿cuál es la mejor manera de asegurar la exclusión mutua?

¿Fue útil?

Solución

Una escritura que está debajo del tamaño de 'PIPE_BUF' se supone que es atómica. Eso debería ser al menos 512 bytes, aunque podría fácilmente ser mayor (Linux parece que lo tiene establecido en 4096).

Este hecho que está hablando todos los componentes totalmente compatible con POSIX. Por ejemplo, esto no es cierto en NFS.

Pero suponiendo que se escribe en un archivo de registro que se abrió en el modo 'O_APPEND' y mantener sus líneas (incluyendo salto de línea) bajo bytes 'PIPE_BUF' de largo, usted debe ser capaz de tener varios escritores a un archivo de registro sin ningún tipo de problemas de corrupción. Cualquier interrupción que llegarán antes o después de la escritura, no en el medio. Si desea presentar la integridad de sobrevivir a un reinicio también necesitará llamar fsync(2) después de cada escritura, pero eso es terrible para el rendimiento.

Aclaración : leer los comentarios y de Oz Salomón respuesta . No estoy seguro de que O_APPEND se supone que tiene que atomicidad tamaño PIPE_BUF. Es muy posible que es sólo la forma en Linux implementa write(), o puede ser debido a los tamaños de bloque del sistema de archivos subyacente.

Otros consejos

Editar:. Actualizado en agosto de 2017 con resultados más recientes de Windows

Me voy a dar una respuesta con enlaces a probar el código y los resultados como el autor de la propuesta Boost.AFIO que implementa un sistema de archivos asíncrona y el archivo de e / S biblioteca de C ++.

En primer lugar, O_APPEND o la FILE_APPEND_DATA equivalente en Windows significa que incrementos de la extensión de archivo máximo (archivo "longitud") son atómica bajo escritores concurrentes. Esto está garantizado por POSIX, y Linux, FreeBSD, OS X y Windows todas implementarlo correctamente. Samba también implementa correctamente, NFS antes v5 no lo hace, ya que carece de la capacidad de formato de alambre para anexar atómicamente. Así que si abre su archivo con sólo anexo, escrituras concurrentes no va a romper con respecto a la otra en cualquier sistema operativo importante a menos NFS está involucrado.

Sin embargo concurrente lee a APPENDs atómicas pueden ver desgarrado escribe dependiendo del sistema operativo, sistema de archivo, y lo que las banderas se abrió el archivo con - el incremento del grado máximo de archivo es atómica, pero la visibilidad de las escrituras con respecto al lee puede ser o no ser atómicas. Aquí es un resumen rápido de banderas, sistema operativo y sistema de archivo:


No O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 con NTFS:. Actualización atomicidad = 1 byte hasta e incluyendo 10.0.10240, desde 10.0.14393 al menos 1Mb, probablemente infinito (*)

Linux 4.2.6 con ext4: actualización de la atomicidad = 1 byte

FreeBSD 10.2 con ZFS: actualización de la atomicidad = al menos 1Mb, probablemente infinito (*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 con NTFS: actualización de la atomicidad = hasta e incluyendo 10.0.10240 hasta 4096 bytes sólo si la página alineados, de lo contrario 512 bytes si fuera FILE_FLAG_WRITE_THROUGH, ELSE 64 bytes. Tenga en cuenta que esta atomicidad es probablemente una característica de PCIe DMA en lugar de en el diseño. Desde 10.0.14393, al menos 1Mb, probablemente infinito (*).

Linux 4.2.6 con ext4: atomicidad actualización = al menos 1Mb, probablemente infinito (*). Tenga en cuenta que Linuxes anteriores con ext4 definitivamente no excedieron de 4096 bytes, XFS sin duda solía tener la costumbre de bloqueo, pero parece que Linux reciente ha fijado finalmente esto.

FreeBSD 10.2 con ZFS: actualización de la atomicidad = al menos 1Mb, probablemente infinito (*)


Puede ver los resultados de las pruebas empíricas primas a https: // github .com / ned14 / afio / árbol / maestro / programas / fs-sonda . Nota ponemos a prueba para las compensaciones rasgados solamente en múltiplos de 512 bytes, por lo que no puedo decir si es una actualización parcial de un sector de 512 bytes se rompiera durante el ciclo de lectura-modificación-escritura.

Por lo tanto, para responder a la pregunta de la OP, O_APPEND escribe no interferirán entre sí, pero lee concurrente a O_APPEND escribe probable que vea desgarrado escribe en Linux con ext4 menos O_DIRECT está encendido, con lo cual sus escrituras O_APPEND tendría que ser un sector tamaño múltiple.


(*) "Probablemente infinita" se deriva de estas cláusulas en la especificación POSIX:

  

Todas las siguientes funciones serán atómica con respecto a cada   otros en los efectos previstos en POSIX.1-2008 cuando operen en las   archivos normales o enlaces simbólicos ... [muchas funciones] ... read () ...   escribir () ... Si dos hilos de cada llamada una de estas funciones, cada llamada   será bien ver a todos los efectos previstos de la otra llamada, o   ninguno de ellos. [Fuente]

y

  

Las escrituras pueden ser serializados con respecto a la otra de lectura y escritura. Si una   read () de datos de archivos puede ser probado (por cualquier medio) a ocurrir después de una   escribir () de los datos, debe reflejar esa escritura (), incluso si las llamadas   son hechos por diferentes procesos. [Fuente]

pero por el contrario:

  

Este volumen de POSIX.1-2008 no especifica el comportamiento de los concurrentes   escribe en un archivo de múltiples procesos. Las aplicaciones deben utilizar algunos   forma de control de concurrencia. [Fuente]

Puede leer más sobre el significado de estos en esta respuesta

Escribí un guión para probar empíricamente el tamaño máximo de agregación atómica. El guión, escrito en bash, genera varios procesos de trabajo, que todos escribimos firmas específico de los trabajadores en el mismo archivo. A continuación, lee el archivo, en busca de firmas que se solapan o dañados. Se puede ver la fuente de la secuencia de comandos en este href="http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/" entrada de blog .

El tamaño de agregación atómica máxima real varía no sólo por el sistema operativo, sino por el sistema de archivos.

En Linux ext3 + el tamaño es de 4096, y en Windows + NTFS el tamaño es de 1024. Véanse los comentarios a continuación para más tamaños.

Esto es lo que la norma dice: http://www.opengroup.org /onlinepubs/009695399/functions/pwrite.html .

  

Si la bandera O_APPEND de los indicadores de estado del archivo se establece, el archivo compensado se establece en el final del archivo antes de cada escritura y ninguna operación de modificación del archivo interviniente deberá producirse entre cambiar el desplazamiento de archivos y la operación de escritura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top