¿Qué sucede cuando lees un archivo mientras se sobrescribe?

¿Qué sucede cuando lees un archivo mientras se sobrescribe?

Supongamos que leo (cat) un archivo mientras otro proceso reescribe su contenido. ¿Es predecible el resultado? ¿Qué pasaría?

Respuesta1

Eso depende de lo que haga el escritor.

Si el escritor sobrescribe el archivo existente, el lector verá el nuevo contenido cuando el escritor supere al lector, si es que alguna vez lo hace. Si el escritor y el lector proceden a velocidades variables, el lector puede ver alternativamente contenido antiguo y nuevo.

Si el escritor trunca el archivo antes de comenzar a escribir, el lector se ejecutará hasta el final del archivo en ese punto.

Si el escritor crea un archivo nuevo y luego lo mueve al nombre anterior, el lector seguirá leyendo el archivo anterior. Si un archivo abierto se mueve o elimina, los procesos que tienen el archivo abierto siguen leyendo ese mismo archivo. Si se elimina el archivo, en realidad permanece en el disco (pero sin forma de volver a abrirlo) hasta que el último proceso lo cierre.

Los sistemas Unix tienden a no tener requisitos obligatorios.Cerraduras. Si una aplicación quiere asegurarse de que su componente escritor y su componente lector no se pisen entre sí, depende del desarrollador utilizar el bloqueo adecuado. Hay algunas excepciones en las que un archivo abierto por el kernel puede estar protegido contra escritura por parte de aplicaciones de usuario, por ejemplo unbucle-Imagen del sistema de archivos montada o un ejecutable que se ejecuta en algunas variantes de Unix.

Respuesta2

Es una condición de carrera clásica, por lo que el resultado es impredecible por definición.

Entre otros, depende de

  • fopen(3)o open(2)modos de escritura,
  • cómo/si el escritor está almacenando en buffer su salida,
  • cómo el lector lee el archivo,
  • la diferencia de velocidad entre el lector y el escritor,
  • la diferencia horaria entre el inicio de la lectura y el inicio del escritor.
  • Y, por supuesto, en las modernas máquinas multinúcleo las cosas se complican aún más por otros factores que se encuentran en un nivel inferior (por ejemplo, la programación de procesos).

Si necesita poder leer un archivo mientras se reescribe, puede hacer que el escritor haga una copia transitoria del archivo, lo modifique y luego lo copie nuevamente al archivo original. Así es como rsyncse hace esto, por ejemplo. Hay varias formas de implementar esto, pero nada gratis. Cada método tiene sus propias deficiencias y repercusiones.

Respuesta3

Los encuestados anteriores tienen explicaciones más completas que esta, pero aquí hay un truco que definitivamente también funciona, haciendo exactamente lo que él quiere:

$ tail -f <filename>

Le mostrará el final del archivo a medida que se escribe. Útil si desea canalizar STDERR a un archivo pero aún verlo en otra ventana de terminal, por ejemplo.

información relacionada