Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Buffer Flush ใน C++: ทำไมต้องใช้ และใช้อย่างไร

Buffer Flush คือการบังคับให้ข้อมูลใน Buffer (หน่วยความจำชั่วคราว) ถูกเขียนออกสู่ Destination (Console, File, Network) ทันที โดยไม่รอให้ Buffer เต็มหรือโปรแกรมจบการทำงาน

ทำไมต้อง Flush?

C++ ใช้ Buffered I/O เพื่อประสิทธิภาพ การเขียนข้อมูลทีละไบต์ช้า มากกว่าการสะสมใน Buffer แล้วส่งทีเดียว แต่ในบางกรณีเราต้องการให้ข้อมูลปรากฏทันที เช่น:

  • แสดง Progress/Loading ใน Console
  • Log ระหว่าง Debugging (ป้องกัน Log หายถ้า Crash)
  • Interactive Program ที่รอ Input จาก User

วิธี Flush ใน C++

  1. std::endl - พิมพ์ Newline แล้ว Flush ทันที
  2. std::flush - Manipulator สำหรับ Flush โดยไม่ใส่ Newline
  3. std::cout.flush() - เรียก Method โดยตรง
  4. std::unitbuf - เปิดโหมด Auto-flush ทุกครั้งที่ Insert (ช้า)

ตัวอย่างเปรียบเทียบ

ไม่ใช้ Flush (Buffered)

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

int main() {
    for (int x = 1; x <= 5; ++x) {
        cout << x << " ";  // ไม่ flush
        this_thread::sleep_for(chrono::seconds(1));
    }
    cout << endl;  // Flush ที่นี่ (จบโปรแกรมก็ flush)
    // ผลลัพธ์: รอ 5 วินาที แล้วแสดง "1 2 3 4 5" พร้อมกัน
}

ใช้ Flush (Unbuffered/Real-time)

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

int main() {
    for (int x = 1; x <= 5; ++x) {
        cout << x << " " << flush;  // Flush ทุกครั้ง
        this_thread::sleep_for(chrono::seconds(1));
    }
    cout << endl;
    // ผลลัพธ์: แสดง "1" รอ 1 วิ แสดง "2" รอ 1 วิ ...
}

กรณีพิเศษ: Input/Output Synchronization

ค่า Default ของ C++ จะ Sync กับ C stdio (stdio.h) ทำให้ cin/cout ช้ากว่า scanf/printf สามารถปิดได้ด้วย:

ios::sync_with_stdio(false);
cin.tie(nullptr);  // Untie cin จาก cout (ไม่ flush cout ก่อนอ่าน cin)

คำเตือน: หากปิด Sync ต้องไม่ผสมใช้ C และ C++ I/O พร้อมกัน

สรุป

Buffer Flush เป็นเทคนิคสำคัญสำหรับ Real-time Output และ Debugging ใช้ flush หรือ endl เมื่อต้องการให้ข้อมูลออกทันที แต่ควรใช้สบายๆ เพราะ Flush บ่อยเกินไปส่งผลต่อ Performance