Wenn die Anwendung keine internen Caches hat, werden die Änderungen sofort in die Datei geschrieben. Dasselbe gilt für dein Beispiel. Die Datei ist eine logische Einheit im Speicher, die sofort aktualisiert wird. Alle nachfolgenden Operationen an der Datei sehen die vom Programm vorgenommenen Änderungen.
Allerdings , bedeutet dies nicht, dass die Änderung auf die physische Festplatte geschrieben wurde. Die Änderungen können in den Dateisystem-Caches oder Hardware-Caches des Betriebssystems verbleiben. Verwenden Sie zum Leeren der Dateisystempuffer den sync
Befehl.
Ich möchte die Datei direkt nach Beendigung des Befehls lesen, aber ich möchte keine leere Datei lesen.
Hier sollten Sie auf keine praktischen Probleme stoßen.
Es sind mehrere Ebenen von Puffern/Caches beteiligt.
-
Der CPU-Cache.
Die Daten werden byteweise zusammengesetzt und im CPU-Cache gespeichert. Wenn der CPU-Cache voll ist und auf die Daten eine Zeit lang nicht zugegriffen wurde, wird der Block mit unseren Daten möglicherweise in den Hauptspeicher geschrieben. Diese sind den Anwendungsprogrammierern größtenteils verborgen.
-
Die prozessinternen Puffer.
Während des Prozesses, in dem die Daten gesammelt werden, wird etwas Speicher reserviert, sodass wir so wenig Anfragen wie möglich an das Betriebssystem stellen müssen, da dies vergleichsweise teuer ist. Der Prozess kopiert die Daten in diese Puffer, die wiederum durch CPU-Caches gesichert werden können, sodass es keine Garantie dafür gibt, dass die Daten in den Hauptspeicher kopiert werden. Die Anwendung muss diese Puffer explizit leeren, zum Beispiel mit fclose(3) oder fsync(3). Die Funktion exit(3) tut dies auch, bevor der Prozess beendet wird, die Funktion _exit(2) nicht , weshalb es in der Handbuchseite eine große Warnung gibt, diese Funktion nur aufzurufen, wenn Sie wissen, was Sie tun.
-
Die Kernel-Puffer
Das Betriebssystem behält dann seinen eigenen Cache, um die Anzahl der Anforderungen zu minimieren, die es an die Festplatten senden muss. Dieser Cache gehört keinem bestimmten Prozess, daher können Daten darin zu Prozessen gehören, die bereits beendet sind, und da alle Zugriffe hier durchlaufen werden, wird das nächste Programm die Daten sehen, wenn es hier angekommen ist. Der Kernel wird diese Daten auf die Platten schreiben, wenn er Zeit dazu hat oder wenn er ausdrücklich darum gebeten wird.
-
Der Laufwerk-Cache
Die Plattenlaufwerke selbst halten auch einen Cache, um Zugriffe zu beschleunigen. Diese werden ziemlich schnell geschrieben, und es gibt einen Befehl, die verbleibenden Daten in die Caches zu schreiben und zu melden, wenn dies abgeschlossen ist, den das Betriebssystem beim Herunterfahren verwendet, um sicherzustellen, dass keine Daten ungeschrieben bleiben, bevor es heruntergefahren wird.
Für Ihre Anwendung reicht es aus, dass die Daten in den Kernelpuffern registriert werden (die eigentlichen Daten befinden sich zu diesem Zeitpunkt möglicherweise noch in CPU-Caches und wurden möglicherweise nicht in den Hauptspeicher geschrieben):Der "Echo" -Prozess wird beendet, was bedeutet, dass alle prozessinternen Puffer geleert und die Daten an das Betriebssystem übergeben werden müssen, und wenn Sie dann einen neuen Prozess starten, ist garantiert, dass das Betriebssystem auf Anfrage dieselben Daten zurückgibt.
Wird der Puffer automatisch auf die Festplatte geleert, wenn ein Prozess beendet wird?
Im Allgemeinen lautet die Antwort nein .
Es kommt auf den Befehl an. Wie die anderen Antworten erwähnen, if Der Befehl puffert die Daten nicht intern, alle Daten sind verfügbar, wenn der Befehl beendet wird.
Aber die meisten, wenn nicht alle Standard-I/O-Bibliotheken tun buffer stdout standardmäßig (bis zu einem gewissen Grad) und geben unterschiedliche Garantien für das automatische Leeren von Puffern, wenn die Anwendung geschlossen wird.
C garantiert, dass ein normaler Exit die Puffer leert. „Normaler Ausgang“ bedeutet, dass exit
aufgerufen — entweder explizit oder durch Rückkehr von main
. Ein abnormales Beenden kann diesen Aufruf jedoch umgehen (und daher nicht geleerte Puffer zurücklassen).
Hier ist ein einfaches Beispiel:
#include <signal.h>
#include <stdio.h>
int main() {
printf("test");
raise(SIGABRT);
}
Wenn Sie dies kompilieren und ausführen, test
wird nicht unbedingt nach stdout geschrieben werden.
Andere Programmiersprachen geben noch weniger Garantien:Java beispielsweise nicht automatische Spülung bei Programmende. Enthält der Ausgabepuffer eine nicht abgeschlossene Zeile, kann diese daher verloren gehen, es sei denn System.out.flush()
wurde explizit aufgerufen.
Allerdings fragt Ihr Fragetext etwas anderes:ob die Daten überhaupt in der Datei ankommen , sollte dies unmittelbar nach Beendigung des Befehls erfolgen (vorbehaltlich der in den anderen Antworten beschriebenen Einschränkungen).