Si la aplicación no tiene cachés internos, los cambios se escribirán inmediatamente en el archivo. Lo mismo para tu ejemplo. El archivo es una entidad lógica en la memoria que se actualizará inmediatamente. Cualquier operación posterior en el archivo verá los cambios realizados por el programa.
Sin embargo , esto no significa que el cambio se haya escrito en el disco físico. Los cambios pueden permanecer en los cachés del sistema de archivos del sistema operativo o en los cachés de hardware. Para vaciar los búferes del sistema de archivos, use el sync
comando.
Me gustaría leer el archivo inmediatamente después de que finalice el comando, pero no quiero leer un archivo vacío.
No debería encontrarse con ningún problema práctico aquí.
Hay varias capas de búfer/caché involucradas.
-
La memoria caché de la CPU.
Los datos se juntan byte por byte y se almacenan en la memoria caché de la CPU. Si la memoria caché de la CPU está llena y no se ha accedido a los datos durante un tiempo, el bloque que contiene nuestros datos puede escribirse en la memoria principal. Estos están, en su mayor parte, ocultos para los programadores de aplicaciones.
-
Los búferes en proceso.
Hay algo de memoria reservada en el proceso en el que se recopilan los datos, por lo que debemos realizar la menor cantidad posible de solicitudes al sistema operativo, ya que es comparativamente costoso. El proceso copia los datos en estos búferes, que nuevamente pueden estar respaldados por cachés de CPU, por lo que no hay garantía de que los datos se copien en la memoria principal. La aplicación necesita vaciar explícitamente estos búferes, por ejemplo, usando fclose(3) o fsync(3). La función exit(3) también hace esto antes de que finalice el proceso, mientras que la función _exit(2) no , por lo que hay una gran advertencia en la página del manual para que esa función la llame solo si sabe lo que está haciendo.
-
Los búferes del kernel
Luego, el sistema operativo mantiene su propio caché para minimizar la cantidad de solicitudes que necesita enviar a los discos. Este caché no pertenece a ningún proceso en particular, por lo que los datos que contiene pueden pertenecer a procesos que ya han finalizado, y dado que todos los accesos pasan por aquí, el próximo programa verá los datos si ha llegado hasta aquí. El núcleo escribirá estos datos en los discos cuando tenga tiempo de hacerlo o cuando se le solicite explícitamente.
-
La memoria caché de la unidad
Las propias unidades de disco también guardan una caché para agilizar los accesos. Estos se escriben con bastante rapidez, y hay un comando para escribir los datos restantes en los cachés e informar cuando se completa, que el sistema operativo usa al apagar para asegurarse de que no queden datos sin escribir antes de apagarse.
Para su aplicación, es suficiente que los datos se registren en los búferes del núcleo (los datos reales aún pueden vivir en los cachés de la CPU en este punto y es posible que no se hayan escrito en la memoria principal):el proceso de "eco" termina, lo que significa que cualquier búfer en proceso debe haberse vaciado y los datos entregados al sistema operativo, y cuando inicia un nuevo proceso, se garantiza que el sistema operativo devolverá los mismos datos cuando se le solicite.
¿Se vaciará automáticamente el búfer al disco cuando finalice un proceso?
En general, la respuesta es no .
Depende del comando. Como mencionan las otras respuestas, si el comando no almacena en búfer los datos internamente, todos los datos estarán disponibles cuando finalice el comando.
Pero la mayoría, si no todas, las bibliotecas de E/S estándar hacen buffer stdout de forma predeterminada (hasta cierto punto) y ofrece diferentes garantías sobre el vaciado automático de los búferes cuando se cierra la aplicación.
C garantiza que una salida normal vaciará los búferes. “Salida normal” significa que exit
se llama, ya sea explícitamente o regresando de main
. Sin embargo, una salida anormal puede eludir esta llamada (y, por lo tanto, dejar atrás los búfer sin vaciar).
He aquí un ejemplo simple:
#include <signal.h>
#include <stdio.h>
int main() {
printf("test");
raise(SIGABRT);
}
Si compilas esto y lo ejecutas, test
no necesariamente se escribirá en stdout.
Otros lenguajes de programación dan aún menos garantías:Java, por ejemplo, no descarga automática al finalizar el programa. Si el búfer de salida contiene una línea sin terminar, puede perderse, a menos que System.out.flush()
fue llamado explícitamente.
Dicho esto, el cuerpo de su pregunta pregunta algo ligeramente diferente:si los datos llegan al archivo en absoluto , debería hacerlo inmediatamente después de que termine el comando (sujeto a las advertencias descritas en las otras respuestas).