据我所知,在默认情况下由C ++所支持的所有流IO缓冲。
这意味着,要输出的数据被放入缓冲区,直到它满,然后发送到输出设备,同样输入,数据读取一次缓冲区是空的......这一切是这样做的贵多少系统通话可能被最小化。
但如何验证行动这一行为。 我的意思是考虑下面的代码
int main()
{
cout << "Hello world\n";
return 0
}
哪里缓冲进入图片浏览? 我知道有缓冲的发生,但如何解释呢? 输出立即在屏幕上看到,所以这可能是一个代码示例实际上在行动中看到缓冲I / O?
试试下面的程序。 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;
}
首先,不是所有的iostream缓存; 缓冲由所附的处理streambuf
。 在的情况下filebuf
(使用ifstream
和ofstream
),那么读取尽可能,直到缓冲器的大小,并且当显式平齐或接近发生输出将刷新上溢出,缓冲器,或当对象被破坏(这隐含调用close)。
的情况下, cout
是有点特别,因为它永远不会破坏,也没有关闭。 还有就是从系统保证flush
将其上至少一次后调用exit
被调用(这是当你从返回会发生什么main
)。 这意味着,从主返回之前的任何输出将被刷新; 如果你使用cout
在静态对象的析构函数,你仍然需要一个明确的冲洗是肯定的。
它也可以以tie
的输出流的输入流; cout
被绑定到cin
默认。 在这种情况下,任何企图从捆绑流输入将刷新输出。
通常的惯例是只使用std::endl
而不是简单地输出'\n'
; std::endl
输出'\n'
,然后刷新流。 对于它是所有输出迅速出现非常重要的溪流,还有一个unitbuf
可以设置,这意味着流将在每年年底被刷新标志<<
操作。 ( std::cerr
有这个缺省设置)。
最后,如果你想看到缓冲的作用,把类似sleep(10)
的输出之后。 如果输出立即出现,它已被刷新; 如果没有它已被缓冲,冲洗后隐含发生sleep
。
试试下面的代码:
int main()
{
for( int i =0 ; i < 10; i ++ )
{
cout << i << " ";
cerr << i << " ";
}
}
经缓冲的输出通常与流对象的破坏冲洗,所以上面的代码将打印(不总是,OFC,但它确实对我用gcc 4.6.3)
0 1 2 3..9
0 1 2 3..9
代替
0 0 1 1 2 2 3 3 .... 9 9
因为无缓冲cerr
印刷马上(第一序列),和缓冲cout
被印刷在的端部main()