Frage

Ich dachte, fsync() tut fflush() intern, so auf einen Stream mit fsync() ist OK. Aber ich bin immer ein unerwartetes Ergebnis, wenn unter Netzwerk-I / O ausgeführt.

Ihr Code-Snippet:

FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* get fd of the FILE pointer */
fd = fileno(fp);
#ifndef WIN32
ret = fsync(fd);
#else
ret = _commit(fd);
fclose(fp);

Aber es scheint _commit() werden die Daten nicht Spülung (Ich habe versucht, auf Windows und die Daten geschrieben wurde auf einem Linux-Dateisystem exportiert).

Wenn ich den Code geändert werden:

FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);   
...   
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);

es spült die Daten.

Ich frage mich, ob _commit() die gleiche Sache wie fflush() tut. Irgendwelche Eingänge?

War es hilfreich?

Lösung

fflush() arbeitet auf FILE*, es spült nur die internen Puffer in der FILE* Ihrer Anwendung heraus an das OS.

fsync Arbeiten auf einem niedrigeren Niveau, es weist das Betriebssystem seine Puffer zu den physikalischen Medien zu spülen.

OSs cachen stark Daten, die Sie in eine Datei schreiben. Wenn das Betriebssystem alle Schreib treffen den Antrieb erzwungen, würde die Dinge sein sehr langsam. fsync (unter anderem) können Sie steuern, wenn die Daten des Antriebs treffen sollte.

Darüber hinaus fsync / commit Arbeiten auf einem Dateideskriptor. Es hat keine Kenntnis von einer FILE* und kann seine Puffer nicht leeren. FILE* Leben in Ihrer Anwendung, lebt Dateideskriptoren in dem OS-Kernel, in der Regel.

Andere Tipps

Die Standard-C-Funktion fflush() und das POSIX-Systemaufruf fsync() sind vom Konzept her ein wenig ähnlich. fflush() arbeitet auf C-Datei-Streams (FILE Objekte), und ist daher tragbar. fsync() arbeiten auf POSIX-Dateibeschreibungen. Beiden Ursachen gepufferten Daten an einen Empfänger gesendet werden.

Auf einem POSIX-System, jeder C Datei-Stream hat eine zugehörige Dateideskriptor , und alle Operationen auf einem C-Datei-Stream werden durch die Delegation bei Bedarf zu POSIX-Systemaufrufen implementiert werden, die auf dem Dateideskriptor arbeiten.

Man könnte meinen, dass ein Aufruf fflush auf einem POSIX-System in dem Puffer des Datei-Stream, einen write von Daten durch einen Aufruf von fsync() für den Dateideskriptor der Datei Stream verursachen würde. So auf einem POSIX-System würde es keine Notwendigkeit, einen Anruf zu fflush mit einem Aufruf an fsync(fileno(fp)) zu folgen. Aber ist das der Fall: es ist ein Aufruf an fsync von fflush

Nein, auf einem POSIX-System fflush Aufruf bedeutet nicht, dass fsync aufgerufen werden.

Der C-Standard für fflush sagt (Hervorhebung hinzugefügt) es

  

bewirkt, dass alle ungeschriebenen Daten für [den] Strom an die Host-Umgebung geliefert werden geschrieben werden in die Datei

Zu sagen, dass die Daten sein geschrieben, anstatt das ist ist geschrieben bedeutet, dass weitere Pufferung von der Host-Umgebung erlaubt. Die durch die „Host-Umgebung“ Pufferung könnte, für eine POSIX-Umgebung, die interne Pufferung, dass fsync Wallungen. So eine genaue Lektüre der C-Norm legt nahe, dass die Norm nicht die POSIX-Implementierung Aufruf fsync erfordert.

Die POSIX-Standard Beschreibung fflush erklärt nicht, wie eine Erweiterung der C-Semantik , dass fsync genannt wird.

Ich könnte sagen, dass der Einfachheit halber:

Verwendung fsync() mit nicht Streaming-Dateien (integer Filedeskriptoren)

Verwendung fflush() mit Datei-Streams.

Auch hier ist die Hilfe von Menschen:

int fflush(FILE *stream); // flush a stream, FILE* type

int fsync(int fd); // synchronize a file's in-core state with storage device
                    // int type

fflush() und fsync() können verwendet werden, um Daten zu versuchen und sicherzustellen, auf das Speichermedium geschrieben sind (aber es ist nicht immer möglich sein):

  1. ersten Gebrauch fflush(fp) auf dem Ausgangsstrom (a fp FILE * aus fopen oder eine der Standardströme stdout oder stderr erhalten wird), um die Inhalte des Puffers mit dem Strom an das OS zugeordnet zu schreiben.
  2. dann fsync(fileno(fp)) verwendet das Betriebssystem zu sagen, seine eigenen Puffer auf das Speichermedium zu schreiben.

Beachten Sie jedoch, dass fileno() und fsync() POSIX-Funktionen, die nicht auf allen Systemen verfügbar sein könnten, insbesondere Microsoft Legacy-Systemen, in denen Alternativen _fileno() genannt werden können, _fsync() oder _commit() ...

Um das Engagement der letzten Änderungen auf der Festplatte zu erzwingen, verwenden Sie die sync () oder fsync () Funktionen.

fsync () werden alle der angegebene Datei der Daten und Metadaten mit dem permanenten Speichergerät synchronisieren. Es sollte nur aufgerufen werden, bevor die entsprechende Datei geschlossen wurde.

sync () werden alle geänderten Dateien auf die Festplatte begehen.

Ich denke, unter Dokument von Python ( https://docs.python.org/ 2 / library / os.html ) stellt klar, es sehr gut.

  

os.fsync (fd) Force-Schreiben von Datei mit FileDescriptor auf der Festplatte fd. Auf   Unix, dies ruft die native fsync () Funktion; unter Windows die MS   _commit () Funktion.

     

Wenn Sie mit einem Python-Datei-Objekt f fangen, erster f.flush tun (),   und dann tun os.fsync (f.fileno ()), um sicherzustellen, dass alle internen Puffer   im Zusammenhang mit f auf der Festplatte geschrieben werden.

     

Verfügbarkeit:. Unix und Windows in 2.2.3 Start

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top