Se l'applicazione non dispone di cache interne, le modifiche verranno immediatamente scritte nel file. Lo stesso per il tuo esempio. Il file è un'entità logica in memoria che verrà immediatamente aggiornata. Eventuali successive operazioni sul file vedranno le modifiche apportate dal programma.
Tuttavia , questo non significa che la modifica è stata scritta sul disco fisico. Le modifiche potrebbero persistere nelle cache del file system del sistema operativo o nelle cache hardware. Per svuotare i buffer del filesystem, usa sync
comando.
Vorrei leggere il file subito dopo l'uscita dal comando, ma non voglio leggere un file vuoto.
Non dovresti incontrare problemi pratici qui.
Sono coinvolti più livelli di buffer/cache.
-
La cache della CPU.
I dati vengono messi insieme byte per byte e memorizzati nella cache della CPU. Se la cache della CPU è piena e non si è avuto accesso ai dati per un po', il blocco contenente i nostri dati potrebbe essere scritto nella memoria principale. Questi sono, per la maggior parte, nascosti ai programmatori dell'applicazione.
-
I buffer in-process.
C'è un po' di memoria riservata nel processo in cui i dati vengono raccolti, quindi dobbiamo fare il minor numero possibile di richieste al sistema operativo, perché è relativamente costoso. Il processo copia i dati in questi buffer, che ancora una volta possono essere supportati dalle cache della CPU, quindi non vi è alcuna garanzia che i dati vengano copiati nella memoria principale. L'applicazione deve svuotare esplicitamente questi buffer, ad esempio utilizzando fclose(3) o fsync(3). Anche la funzione exit(3) fa questo prima che il processo sia terminato, mentre la funzione _exit(2) non , motivo per cui c'è un grande avvertimento nella pagina di manuale per quella funzione per chiamarla solo se sai cosa stai facendo.
-
I buffer del kernel
Il sistema operativo mantiene quindi la propria cache, per ridurre al minimo il numero di richieste che deve inviare ai dischi. Questa cache non appartiene a nessun processo in particolare, quindi i dati in essa contenuti potrebbero appartenere a processi che sono già terminati e poiché tutti gli accessi passano da qui, il programma successivo vedrà i dati se è arrivato qui. Il kernel scriverà questi dati sui dischi quando avrà il tempo di farlo o quando richiesto esplicitamente.
-
La cache dell'unità
Le stesse unità disco mantengono anche una cache per velocizzare gli accessi. Questi vengono scritti abbastanza rapidamente e c'è un comando per scrivere i dati rimanenti nelle cache e segnalare quando è completo, che il sistema operativo utilizza all'arresto per assicurarsi che nessun dato venga lasciato non scritto prima dello spegnimento.
Per la tua applicazione, è sufficiente che i dati siano registrati nei buffer del kernel (i dati effettivi potrebbero ancora risiedere nelle cache della CPU a questo punto e potrebbero non essere stati scritti nella memoria principale):il processo "echo" termina, che significa che tutti i buffer in-process devono essere stati scaricati e che i dati sono stati consegnati al sistema operativo, e quando si avvia un nuovo processo, è garantito che il sistema operativo restituirà gli stessi dati quando richiesto.
Il buffer verrà scaricato automaticamente su disco quando un processo termina?
In generale la risposta è no .
Dipende dal comando. Come menzionano le altre risposte, if il comando non esegue il buffer interno dei dati, tutti i dati saranno disponibili al termine del comando.
Ma la maggior parte, se non tutte, le librerie I/O standard lo fanno buffer stdout per impostazione predefinita (in una certa misura) e fornisce diverse garanzie sullo svuotamento automatico dei buffer alla chiusura dell'applicazione.
C garantisce che un'uscita normale svuoterà i buffer. "Uscita normale" significa che exit
viene chiamato — esplicitamente o ritornando da main
. Tuttavia, un'uscita anomala può aggirare questa chiamata (e quindi lasciare dietro di sé buffer non svuotati).
Ecco un semplice esempio:
#include <signal.h>
#include <stdio.h>
int main() {
printf("test");
raise(SIGABRT);
}
Se lo compili e lo esegui, test
non essere necessariamente scritto su stdout.
Altri linguaggi di programmazione danno ancora meno garanzie:Java, per esempio, non lavaggio automatico al termine del programma. Se il buffer di output contiene una riga non terminata, potrebbe quindi essere persa, a meno che System.out.flush()
è stato chiamato esplicitamente.
Detto questo, il corpo della tua domanda chiede qualcosa di leggermente diverso:se i dati arrivano nel file per niente , dovrebbe farlo immediatamente dopo che il comando è terminato (soggetto agli avvertimenti descritti nelle altre risposte).