C ++缓冲流IO(C++ buffered stream IO)

2019-06-26 03:30发布

据我所知,在默认情况下由C ++所支持的所有流IO缓冲。

这意味着,要输出的数据被放入缓冲区,直到它满,然后发送到输出设备,同样输入,数据读取一次缓冲区是空的......这一切是这样做的贵多少系统通话可能被最小化。

但如何验证行动这一行为。 我的意思是考虑下面的代码

int main()
{
    cout << "Hello world\n";
    return 0
}

哪里缓冲进入图片浏览? 我知道有缓冲的发生,但如何解释呢? 输出立即在屏幕上看到,所以这可能是一个代码示例实际上在行动中看到缓冲I / O?

Answer 1:

试试下面的程序。 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;
}


Answer 2:

首先,不是所有的iostream缓存; 缓冲由所附的处理streambuf 。 在的情况下filebuf (使用ifstreamofstream ),那么读取尽可能,直到缓冲器的大小,并且当显式平齐或接近发生输出将刷新上溢出,缓冲器,或当对象被破坏(这隐含调用close)。

的情况下, cout是有点特别,因为它永远不会破坏,也没有关闭。 还有就是从系统保证flush将其上至少一次后调用exit被调用(这是当你从返回会发生什么main )。 这意味着,从主返回之前的任何输出将被刷新; 如果你使用cout在静态对象的析构函数,你仍然需要一个明确的冲洗是肯定的。

它也可以以tie的输出流的输入流; cout被绑定到cin默认。 在这种情况下,任何企图从捆绑流输入将刷新输出。

通常的惯例是只使用std::endl而不是简单地输出'\n' ; std::endl输出'\n' ,然后刷新流。 对于它是所有输出迅速出现非常重要的溪流,还有一个unitbuf可以设置,这意味着流将在每年年底被刷新标志<<操作。 ( std::cerr有这个缺省设置)。

最后,如果你想看到缓冲的作用,把类似sleep(10)的输出之后。 如果输出立即出现,它已被刷新; 如果没有它已被缓冲,冲洗后隐含发生sleep



Answer 3:

试试下面的代码:

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()



文章来源: C++ buffered stream IO