Si l'application n'a pas de caches internes, les modifications seront immédiatement écrites dans le fichier. Idem pour votre exemple. Le fichier est une entité logique en mémoire qui sera immédiatement mise à jour. Toutes les opérations ultérieures sur le fichier verront les modifications apportées par le programme.
Cependant , cela ne signifie pas que la modification a été écrite sur le disque physique. Les modifications peuvent persister dans les caches du système de fichiers du système d'exploitation ou les caches matériels. Pour vider les tampons du système de fichiers, utilisez le sync
commande.
J'aimerais lire le fichier juste après la sortie de la commande, mais je ne veux pas lire un fichier vide.
Vous ne devriez pas rencontrer de problèmes pratiques ici.
Plusieurs couches de tampons/caches sont impliquées.
-
Le cache du processeur.
Les données sont assemblées octet par octet et stockées dans le cache du CPU. Si le cache du processeur est plein et que les données n'ont pas été consultées pendant un certain temps, le bloc contenant nos données peut être écrit dans la mémoire principale. Ceux-ci sont, pour la plupart, cachés aux programmeurs d'applications.
-
Les tampons en cours de traitement.
Il y a une certaine mémoire réservée dans le processus où les données sont collectées, nous devons donc faire le moins de demandes possible au système d'exploitation, car cela coûte relativement cher. Le processus copie les données dans ces tampons, qui peuvent à nouveau être sauvegardés par des caches CPU, il n'y a donc aucune garantie que les données soient copiées dans la mémoire principale. L'application doit explicitement vider ces tampons, par exemple en utilisant fclose(3) ou fsync(3). La fonction exit(3) le fait également avant la fin du processus, tandis que la fonction _exit(2) ne le fait pas , c'est pourquoi il y a un gros avertissement dans la page de manuel pour que cette fonction ne l'appelle que si vous savez ce que vous faites.
-
Les tampons du noyau
Le système d'exploitation conserve alors son propre cache, afin de minimiser le nombre de requêtes qu'il doit envoyer aux disques. Ce cache n'appartient à aucun processus en particulier, donc les données qu'il contient peuvent appartenir à des processus qui sont déjà terminés, et puisque tous les accès passent par ici, le programme suivant verra les données s'il a atteint ici. Le noyau écrira ces données sur les disques lorsqu'il aura le temps de le faire ou sur demande explicite.
-
Le cache du lecteur
Les disques eux-mêmes conservent également un cache pour accélérer les accès. Celles-ci sont écrites assez rapidement, et il existe une commande pour écrire les données restantes dans les caches et signaler quand cela est terminé, que le système d'exploitation utilise à l'arrêt pour s'assurer qu'aucune donnée n'est laissée non écrite avant de s'éteindre.
Pour votre application, il suffit que les données soient enregistrées dans les tampons du noyau (les données réelles peuvent encore vivre dans les caches CPU à ce stade, et peuvent ne pas avoir été écrites dans la mémoire principale) :le processus "echo" se termine, ce qui signifie que tous les tampons en cours doivent avoir été vidés et les données transmises au système d'exploitation, et lorsque vous démarrez un nouveau processus, il est garanti que le système d'exploitation restituera les mêmes données lorsqu'on lui demandera.
Le tampon sera-t-il automatiquement vidé sur le disque lorsqu'un processus se termine ?
En général, la réponse est non .
Cela dépend de la commande. Comme le mentionnent les autres réponses, si la commande ne tamponne pas les données en interne, toutes les données seront disponibles lorsque la commande se terminera.
Mais la plupart, sinon la totalité, des bibliothèques d'E/S standard le font tampon stdout par défaut (dans une certaine mesure), et donner différentes garanties sur le vidage automatique des tampons à la fermeture de l'application.
C garantit qu'une sortie normale videra les tampons. "Sortie normale" signifie que exit
est appelé — soit explicitement, soit en revenant de main
. Cependant, une sortie anormale peut contourner cet appel (et donc laisser des tampons non vidés).
Voici un exemple simple :
#include <signal.h>
#include <stdio.h>
int main() {
printf("test");
raise(SIGABRT);
}
Si vous le compilez et l'exécutez, test
ne va pas nécessairement être écrit sur stdout.
D'autres langages de programmation offrent encore moins de garanties :Java, par exemple, ne le fait pas rinçage automatique à la fin du programme. Si le buffer de sortie contient une ligne non terminée, elle peut donc être perdue, sauf si System.out.flush()
a été appelé explicitement.
Cela dit, le corps de votre question demande quelque chose de légèrement différent :si les données arrivent dans le fichier du tout , il devrait le faire immédiatement après la fin de la commande (sous réserve des mises en garde décrites dans les autres réponses).