【问题标题】:Case(s) where output buffer won't flush?输出缓冲区不会刷新的情况?
【发布时间】:2018-04-17 13:04:02
【问题描述】:

我正在学习 iostream 对象并刷新缓冲区。我知道何时保证刷新输出缓冲区以及如何显式刷新缓冲区。但是,我从未见过刷新输出缓冲区的情况。在我看来,即使我不使用 endlflushends 等操纵器,输出缓冲区也会在每个语句的末尾被刷新。

那么,是否有任何简单的示例输出缓冲区不会(或至少可能经常不会)被刷新?我觉得我需要看到这样的案例才能真正理解输出缓冲区。

【问题讨论】:

  • 请记住,涉及到两个级别的缓冲和刷新:上游对象内部的缓冲,默认情况下为 cout 关闭,以及操作系统中的流缓冲。
  • @MikeMB cout 是否关闭了缓冲?你的意思是unitbuf?如果没有,我可以打开它吗?

标签: c++ buffer iostream outputstream


【解决方案1】:

取决于系统。

以下面的程序为例:

#include <iostream>
#ifdef WIN32
#include <windows.h>
#define sleep(n) Sleep((n)*1000)
#else
#include <unistd.h>
#endif

using namespace std;

int main()
{
    cout << "This is line 1";
    sleep(4);
    cout << endl;
    cout << "This is line 2" << endl;

    return 0;
}

通过检查程序,您可能会推测该程序将打印This is line 1,然后暂停 4 秒,然后打印This is line 2

如果您使用 Visual Studio 编译以在 Windows 上运行,您将获得准确的行为。

然而,在 Linux 和其他 Unix 操作系统上,程序会在打印出两行之前显示为静默 4 秒。在输出流中遇到换行符之前,输出不会可靠地刷新。

【讨论】:

  • 啊,所以它依赖于系统。这就是为什么自从我使用 Visual Studio 以来我从未见过这种情况。谢谢!
  • “在输出流中遇到换行符之前,输出不会可靠刷新”不是完全正确的。换行符\n 确实不会 导致刷新,但std::endl 会因为它输出换行符然后执行std::flush。这就是 std::endl 在某些情况下相当昂贵的原因,以及为什么人们应该更喜欢使用 \n,除非也明确需要/想要刷新 - 在这种情况下,std::endl 是正确的工具。
  • @JesperJuhl:您必须区分 std::cout 和文件流,并在 iostream 对象中缓冲和在操作系统/控制台窗口中缓冲。默认情况下 std::cout 不缓冲任何内容,而是将每个输入直接发送到操作系统(例如通过 linux 上的write),并且通常在接收换行符(或更早)时刷新自己的缓冲区。在这种模式下,使用\nstd::endl 几乎没有区别。如果您在 iostream 对象中激活缓冲(或使用文件流),那么您是完全正确的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 2022-10-02
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 1970-01-01
相关资源
最近更新 更多