Die Eingabe-Ausgabe-Pufferung (IO-Pufferung) gibt es in der Programmiersprache C seit der Einführung der Standardbibliothek (stdio). Sie wurde eingeführt, um die Leistung von Lese- und Schreiboperationen zu verbessern, da der Zugriff auf Festplatten oder Geräte eine zeitaufwändige Operation darstellt, und die Pufferung hilft, die Anzahl dieser Zugriffe zu verringern.
Ein Unverständnis der Pufferung kann zu unerwarteten Verzögerungen bei der Ein- und Ausgabe, Datenverlust bei einem unerwarteten Programmabbruch, Fehlern beim Arbeiten mit mehreren Threads (insbesondere bei stdout/stderr) und Synchronisierungsfehlern zwischen Prozessen oder Systemen führen.
Da Datei-Streams gepuffert, zeilenweise gepuffert oder unpuffert sein können, ist es wichtig, die Funktionen zum zwangsweisen Leeren des Puffers (fflush()) zu verwenden, Dateien ordnungsgemäß zu schließen (fclose()), und die Arbeit mit stdin, stdout und stderr sinnvoll zu kombinieren. Die Pufferung hängt auch vom Typ des Streams ab (z.B. wird stdout beim Ausgeben des Zeichens in einem mit dem Terminal verbundenen Stream geleert, aber nicht immer — wenn es sich um eine Datei handelt).
Beispielcode:
#include <stdio.h> int main() { printf("Hallo"); // sleep(10); // kein Output vor fflush fflush(stdout); // gibt den Puffer sofort auf dem Bildschirm aus return 0; }
Wichtige Merkmale:
fflush() — das Hauptinstrument zum manuellen Leeren des PuffersKann man sich darauf verlassen, dass die Ausgabe von printf sofort auf dem Bildschirm erscheint?
Nein, wenn die Ausgabe nicht ins Terminal, sondern zum Beispiel in eine Datei geht — die Zeilen erscheinen nicht, bis ein Puffergeschirr erfolgt oder die Puffergrenze erreicht wird. Selbst im Terminal kann eine Zeile ohne nicht sofort erscheinen. Verwenden Sie fflush(stdout); für eine sofortige Ausgabe.
Was passiert, wenn fflush(stdin) aufgerufen wird?
Dies ist undefined behavior gemäß dem C-Standard. Einige Compiler/Plattformen können den Eingabestrompuffer leeren, aber dies ist im Standard nicht garantiert und dieser Ansatz ist nicht portabel und potenziell gefährlich.
Kann man printf und fprintf(stderr, ...) als äquivalent für sofortige Ausgabe betrachten?
Nein. Der Standardausgang (stdout) wird normalerweise vollständig oder zeilenweise gepuffert, stderr wird standardmäßig immer ungesichert gepuffert. Das heißt, die Ausgabe an stderr erscheint sofort auf dem Bildschirm, die Ausgabe an stdout nicht.
fflush(stdin) zum Leeren des EingabepuffersDas Programm schreibt eine Logdatei über printf, ruft jedoch fflush(stdout) nicht auf und schließt die Datei nicht im Falle eines unerwarteten Absturzes.
Vorteile:
Nachteile:
Das Programm ruft nach jedem wichtigen Logeintrag fflush(stdout) auf oder schreibt kritische Nachrichten in stderr.
Vorteile:
Nachteile: