【问题标题】:trying to understand the effect of flushing a buffer problem试图了解刷新缓冲区问题的影响
【发布时间】:2021-04-19 19:41:46
【问题描述】:

我完全是 C++ 初学者,所以如果我的问题听起来很愚蠢,我深表歉意。

我一直在阅读一本关于流缓冲区的简单介绍的书,在某些情况下刷新缓冲区很重要,因此为了理解效果,我运行了以下代码:

代码1:

#include <iostream>
#include <thread>
#include <chrono>   
using namespace std;
      
int main()
{
  for (int i = 1; i <= 5; ++i)
  {
      cout << i << " ";
      this_thread::sleep_for(chrono::seconds(1));
  }
  cout << endl;
  return 0;
}

代码2:

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

int main()
{
   for (int i = 1; i <= 5; ++i)
   {
      cout << i << " " << flush;
      this_thread::sleep_for(chrono::seconds(1));
   }
   return 0;
}

两个代码给出相同的输出,完全没有区别,它们打印 1 sleep for 1 second then 2, sleep for another second,依此类推。

我尝试在 DevC++ 和 CodeBlocks 中运行代码,结果相同。

书上说code1的结果——>“程序等待5秒,一次打印所有数字”,code2的结果——>“程序打印数字等待1秒,打印第二个数字等等”。

我真的不明白出了什么问题。

【问题讨论】:

  • 尝试从命令行运行已编译的非flushing 程序。如果您从 IDE 中运行它,它可能会自动刷新缓冲区。例如,如果我在我的 linux bash shell 中运行它,它会等待 5 秒,然后一次打印所有五个数字。
  • cout 输出通常被缓冲,但不是必需。本书描述的两种行为是大多数实现中的典型行为,当cout 是行缓冲时,这意味着在打印换行符(或缓冲区填满)之前不会刷新缓冲区. std::endlstd::flush 都强制立即刷新

标签: c++ c++11 buffer


【解决方案1】:

下面是一个使用和不使用异常刷新的示例(应该在最后一行被刷新之前终止程序):

#include <iostream>
int main() {
    std::cout << "test with flush" << std::flush;
    std::cout << "test without flush";
    throw;
}

当在godbolt 编译和运行时,我明白了:

Program returned: 139
terminate called without an active exception
test with flush

但没有提到“没有刷新的测试”,因为程序在它可以自动刷新之前就结束了。

【讨论】:

  • 这如何解释为什么 OP 看不到代码 1 和代码 2 的任何区别?根据 OP 所说,OP 使用的环境可能实际上显示 test without flush
  • 确实如此。我的想法是使用相同的 Godbolt 配置应该会产生相同的输出 - 睡眠的东西在那里并没有真正起作用,因为它一次推送所有输出
猜你喜欢
  • 2014-10-01
  • 2012-04-12
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多