Pregunta ¿Cómo puedo sincronizar, hacer atómico, escribir en un archivo desde dos procesos?


Tengo dos procesos que escriben grandes búferes de datos, y quiero controlar la sincronización de las escrituras de esos procesos en un archivo.

el búfer de escritura A del proceso 1 incluye (A1, A2, A3) y el búfer de escritura B del proceso 1, que incluye (B1, B2, B3). cuando usamos write() llamada al sistema para escribir estos búferes en el disco en el mismo archivo (búfer completo a la vez: write(fd, A, sizeof(A))), ¿Cómo es el esquema del archivo?

  • ¿Es así: A, B o B, A tal vez?
  • o podría ser así: A1, A2, B1, A3, ...

Te lo pregunto porque las llamadas al sistema son atómicas. ¿Qué sucede si el buffer de datos que estamos escribiendo es demasiado grande? ¿Es como tuberías para archivos de disco regulares?


6
2017-08-01 08:42


origen


Respuestas:


Si desea que el contenido de ambos búferes esté presente, debe abrir los archivos con el O_APPEND conjunto de banderas. El indicador de agregar busca al final del archivo antes de escribir. Sin este conjunto, es posible que ambos procesos apunten a las mismas áreas del archivo o que se superpongan, y quien escriba último sobrescribirá lo que el otro ha escrito.

Cada llamada a write escribirá hasta el número de bytes solicitados. Si su proceso es interrumpido por una señal, entonces puede terminar con una escritura parcial: se devuelve el número real de bytes escritos. Ya sea que haya escrito todos sus bytes o no, habrá escrito una sección contigua del archivo. No obtiene el efecto de intercalación que mencionó como su segunda posibilidad (por ejemplo, A1, B1, A2, B2, ...).

Si solo obtiene una escritura parcial, la forma de proceder depende de usted. Puede continuar escribiendo (desplazamiento desde el inicio del búfer por el número de bytes escritos previamente), o puede abandonar el resto de su escritura. Solo de esta manera podría potencialmente obtener el efecto de intercalación.

Si es importante tener el contenido de una escritura completa antes de que el otro proceso lo escriba, entonces debe buscar bloquear el archivo para acceso de escritura exclusivo (que ambos procesos deberán verificar) antes de intentar escribir cualquier dato.


4
2017-08-01 09:31



Suponiendo que los búferes son de igual tamaño, el resultado será A o B, dependiendo del proceso que se programó en último lugar.

La llamada al sistema de escritura es atómica, sí, lo que significa que el resultado será A o B, no una mezcla de ambos.

Suponiendo que desea que A y B estén en el archivo, puede abrir el archivo con O_APPEND; Tenga en cuenta que esto no funcionará sobre NFS, sin embargo.

Otra opción es que cada proceso realiza un seguimiento de la compensación de archivos que debe usar y utiliza lseek () o pwrite ()


2
2017-08-01 09:22



Definitivamente necesita alguna forma de sincronización para sus programas que acceden al archivo, o termina con el contenido del archivo desordenado. los write la llamada al sistema puede escribir menos bytes de los solicitados, por lo que sus bloques A1, A2 o B1, B2 solo pueden escribirse parcialmente. Esto puede suceder a menudo, o rara vez, dependiendo de muchas condiciones. Si solo ocurre una vez en una semana, tendrá un error que puede ser muy difícil de detectar.

Como solución, puede utilizar el bloqueo de archivos (man 2 flock o man fcntl y buscar el bloqueo). Otra posibilidad es usar semáforos (man -k semaphore) para sincronizar las escrituras de sus programas, o algunas otras formas de IPC.


2
2017-08-01 11:22