Aru*_*run 3 c++ iostream buffered
据我所知,默认情况下,C++支持的所有流IO都是缓冲的.
这意味着要输出的数据被放入缓冲区直到它已满,然后被发送到输出设备,类似于输入,一旦缓冲区为空,就会读取数据...所有这一切都是为了使数量昂贵的系统电话可以最小化.
但是如何验证这种行为.我的意思是考虑以下代码
int main()
{
cout << "Hello world\n";
return 0
}
Run Code Online (Sandbox Code Playgroud)
缓冲在哪里成像?我知道有缓冲发生,但如何解释呢?屏幕上会立即看到输出,那么实际看到缓冲I/O的代码示例是什么呢?
首先,并非所有iostream都被缓冲; 缓冲由附件处理
streambuf.在filebuf(由ifstream和使用
ofstream)的情况下,输入将尽可能多地读取,直到缓冲区的大小,并且当发生显式刷新或关闭时,或者当对象被破坏时,输出将在溢出时刷新缓冲区(隐含地调用close).
这种情况cout有点特殊,因为它永远不会被破坏也不会被关闭.系统保证在flush被调用后至少exit调用一次(这是从你返回时发生的事情main).这意味着从main返回之前的任何输出都将被刷新; 如果你在cout静态对象的析构函数中使用,你仍然需要一个明确的刷新来确定.
tie输出流也可以输出到输入流; 默认cout
绑定cin.在这种情况下,任何从绑定流输入的尝试都将刷新输出.
通常的惯例是使用std::endl而不是简单地输出'\n'; std::endl输出a '\n'然后刷新流.对于所有输出都很快出现非常重要的流,有一个unitbuf可以设置的标志,这意味着流将在每个<<运算符的末尾刷新.(std::cerr默认情况下设置此项.)
最后,如果你想看到缓冲的效果,可以
sleep(10)在你的输出之后输入.如果输出立即显示,则表示已刷新; 如果它没有被缓冲,并且在之后隐式发生了冲洗sleep.
试试下面的程序。sleep(1)用于引入延迟(1 秒),我使用的是 linux,所以sleep对我有用。如果你不能让它工作,请尝试其他方法来延迟这个程序(例如,简单for循环)。如果您没有看到任何缓冲效果,您也可以尝试增加缓冲区大小(取消注释注释的代码行)。
在我的 OS( Linux 3.2.0) 和编译器 ( g++ 4.6.3) 上,该程序打印“Portion1Portion2”,然后是“Portion3Portion4”,然后是“Portion5”。std::endl保证刷新缓冲区,但正如你所看到的,换行符对我来说也是如此。
#include <iostream>
#include <unistd.h>
using namespace std;
int main () {
// Try uncommenting following lines to increase buffer size
// char mybuf[1024];
// cout.rdbuf()->pubsetbuf(mybuf, 1024);
cout << "Portion1";
sleep(1);
cout << "Portion2\n";
sleep(1);
cout << "Portion3";
sleep(1);
cout << "Portion4" << endl;
sleep(1);
cout << "Portion5" << endl;
sleep(1);
cout << "Done!" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)