Unterschied zwischen fflush und fsync

Lesezeit: 6 Minuten

Adils Benutzeravatar
Adil

ich dachte fsync() tut fflush() intern, also mit fsync() auf einem Stream ist OK. Aber ich erhalte ein unerwartetes Ergebnis, wenn ich unter Netzwerk-E/A ausgeführt werde.

Mein Codeschnipsel:

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() löscht die Daten nicht (ich habe es unter Windows versucht und die Daten wurden auf ein exportiertes Linux-Dateisystem geschrieben).

Als ich den Code geändert habe zu:

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 löscht die Daten.

Ich frage mich, ob _commit() macht das gleiche wie fflush(). Irgendwelche Eingänge?

  • Was ist das Problem, das Sie beim ersten Beispiel gesehen haben?

    – Rogerpack

    8. November 2012 um 0:16 Uhr

  • @rogerdpack im ersten Beispiel wird das Schreiben in den Stream über fputs () nicht synchronisiert / auf die Festplatte übertragen, selbst wenn die Funktion _commit () auf dem fd (Dateideskriptor) aufgerufen wird. Dieser Test wurde unter einem Clustersystem durchgeführt, in dem das Remote-Linux-Dateisystem als CIFS exportiert und auf einem Windows-Computer verwendet wird und ein Knoten-Failover während des Schreibens getestet wird. Bei der Wiederherstellung des Knotens wurde festgestellt, dass die Dateigröße Null ist.

    – Adil

    9. November 2012 um 12:26 Uhr

  • Wo ist #endif?

    – binki

    25. November 2016 um 18:56 Uhr

  • Die Frage war intern konsistent und die Antworten stimmten damit vor der Überarbeitung Nr. 5 überein, die die Art der Frage grundlegend veränderte. Auf Revision Nr. 4 zurückgesetzt.

    – Johannes Bollinger

    12. Januar 2017 um 14:38 Uhr

Benutzeravatar von nos
Nr

fflush() arbeitet an FILE*es löscht nur die internen Puffer in der FILE* Ihrer Anwendung an das Betriebssystem.

fsync auf einer niedrigeren Ebene arbeitet, weist es das Betriebssystem an, seine Puffer auf die physischen Medien zu leeren.

Betriebssysteme speichern Daten, die Sie in eine Datei schreiben, stark. Wenn das Betriebssystem jeden Schreibvorgang erzwingen würde, um auf das Laufwerk zu gelangen, wären die Dinge so sehr langsam. fsync (unter anderem) können Sie steuern, wann die Daten auf das Laufwerk gelangen sollen.

Darüber hinaus arbeitet fsync/commit mit einem Dateideskriptor. Es hat keine Kenntnis von a FILE* und kann seine Puffer nicht leeren. FILE* lebt in Ihrer Anwendung, Dateideskriptoren leben normalerweise im Betriebssystemkernel.

  • Danke, ich dachte in die gleiche Richtung. Wenn wir also FILE* verwenden, kann dasselbe durch fflush() gefolgt von fsync() erreicht werden.

    – Adil

    26. Februar 2010 um 9:48 Uhr

  • Nein, weil du es nicht kannst fsync a FILE*.

    – Pattivácek

    26. März 2014 um 16:37 Uhr

  • @patrickvacek tatsächlich können Sie den Dateideskriptor abrufen FILE * verwenden int fileno(FILE * stream); aus stdio.h.

    – Jotik

    11. August 2014 um 13:48 Uhr

  • @jotik: Du solltest verwenden entweder (Standard) FILE * Funktionen, oder (Betriebssystem) Dateihandles. Sie mischen sie nicht. Und fileno() ist keine Standardfunktion. Leider sind die Leute notorisch nachlässig mit dem “Erweitern” von Standard-Headern …

    – DevSolar

    4. Februar 2015 um 15:32 Uhr


  • @DevSolar – fileno() ist Teil des POSIX-Standards, also obwohl es nicht unbedingt portabel ist, ist es auf einigen Plattformen Standard.

    – Josh Kelley

    19. August 2015 um 20:06 Uhr

Benutzeravatar von Raedwald
Raedwald

Die Standard-C-Funktion fflush() und der POSIX-Systemaufruf fsync() sind konzeptionell etwas ähnlich. fflush() arbeitet mit C-Datei-Streams (FILE Objekte) und ist daher portabel.
fsync() arbeiten mit POSIX-Dateideskriptoren. Beide bewirken, dass gepufferte Daten an ein Ziel gesendet werden.

Auf einem POSIX-System jeder C-Dateistream hat einen zugehörigen Dateideskriptorund alle Operationen auf einem C-Dateistrom werden implementiert, indem bei Bedarf POSIX-Systemaufrufe delegiert werden, die auf dem Dateideskriptor arbeiten.

Man könnte meinen, dass ein Anruf an fflush auf einem POSIX-System würde a verursachen write aller Daten im Puffer des Dateistroms, gefolgt von einem Aufruf von fsync() für den Dateideskriptor dieses Dateistreams. Auf einem POSIX-System wäre es also nicht nötig, einem Aufruf zu folgen fflush mit einem Anruf bei fsync(fileno(fp)). Aber ist das der Fall: gibt es einen Aufruf dazu fsync aus fflush?

Nein, Anruf fflush auf einem POSIX-System bedeutet dies nicht fsync wird angerufen werden.

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

verursacht alle ungeschriebenen Daten für [the] Stream, der an die Hostumgebung geliefert werden soll geschrieben werden zur Datei

Sagen, dass die Daten sind sein geschrieben, anstatt das ist ist geschrieben impliziert, dass eine weitere Pufferung durch die Hostumgebung erlaubt ist. Diese Pufferung durch die “Host-Umgebung” könnte für eine POSIX-Umgebung die interne Pufferung umfassen fsync errötet. Eine genaue Lektüre des C-Standards legt also nahe, dass der Standard nicht erfordert, dass die POSIX-Implementierung aufgerufen wird fsync.

Das POSIX-Standardbeschreibung von fflush erklärt nicht, als ein Erweiterung der C-Semantikdas fsync wird genannt.

Benutzeravatar von chqrlie
chqrlie

fflush() und fsync() kann verwendet werden, um sicherzustellen, dass Daten auf das Speichermedium geschrieben werden (aber es ist nicht immer möglich):

  1. erste Benutzung fflush(fp) auf dem Ausgabestrom (fp sein FILE * erhalten von fopen oder einen der Standardstreams stdout oder stderr), um den Inhalt des Puffers, der dem Stream zugeordnet ist, in das Betriebssystem zu schreiben.
  2. dann benutze fsync(fileno(fp)) um das Betriebssystem anzuweisen, seine eigenen Puffer auf die Speichermedien zu schreiben.

Beachte das aber fileno() und fsync() sind POSIX-Funktionen, die möglicherweise nicht auf allen Systemen verfügbar sind, insbesondere auf Microsoft-Legacy-Systemen, auf denen Alternativen genannt werden können _fileno(), _fsync() oder _commit()

  • Dies ist die einzige Antwort, die den vollständigen Prozess erklärt, der den Aufruf beider erfordert fflush und fsync Also ich mag diese Antwort am besten.

    – Benutzer8128167

    26. Oktober 2021 um 18:12 Uhr


Ich könnte der Einfachheit halber sagen:

verwenden fsync() mit Nicht-Streaming-Dateien (ganzzahlige Dateideskriptoren)

verwenden fflush() mit Dateistreams.

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

Verwenden Sie die Funktionen sync() oder fsync(), um die Festschreibung der letzten Änderungen auf der Festplatte zu erzwingen.

fsync() synchronisiert alle Daten und Metadaten der angegebenen Datei mit dem permanenten Speichergerät. Es sollte kurz vor dem Schließen der entsprechenden Datei aufgerufen werden.

synchronisieren () schreibt alle geänderten Dateien auf die Festplatte.

  • Wir diskutieren den Unterschied b/w fsync Vs fflush

    – Bhupesh-Hose

    6. Dezember 2017 um 13:12 Uhr

Benutzeravatar von poordeveloper
schlechter Entwickler

Ich denke, das folgende Dokument von Python (https://docs.python.org/2/library/os.html) verdeutlicht es sehr gut.

os.fsync(fd) Erzwingt das Schreiben einer Datei mit dem Dateideskriptor fd auf die Festplatte. Unter Unix ruft dies die native fsync()-Funktion auf; unter Windows die MS-Funktion _commit().

Wenn Sie mit einem Python-Dateiobjekt f beginnen, führen Sie zuerst f.flush() und dann os.fsync(f.fileno()) aus, um sicherzustellen, dass alle mit f verknüpften internen Puffer auf die Festplatte geschrieben werden.

Verfügbarkeit: Unix und Windows ab 2.2.3.

  • Wir diskutieren den Unterschied b/w fsync Vs fflush

    – Bhupesh-Hose

    6. Dezember 2017 um 13:12 Uhr

1416250cookie-checkUnterschied zwischen fflush und fsync

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy