4

デフォルトでは、C++ でサポートされているすべてのストリーム IO がバッファリングされることを理解しています。

これは、出力されるデータがいっぱいになるまでバッファーに入れられてから出力デバイスに送信されることを意味します。入力の場合と同様に、バッファーが空になるとデータが読み取られます...これはすべて行われるため、高価なシステムの数が少なくなります。通話を最小限に抑えることができます。

ただし、この動作を実際に確認する方法。つまり、次のコードを検討してください

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

ここでバッファリングはどこに現れますか? バッファリングが発生していることは知っていますが、それを説明するにはどうすればよいですか? 出力は画面にすぐに表示されるので、バッファリングされた I/O の動作を実際に確認するコード例は何でしょうか?

4

3 に答える 3

8

まず、すべての iostream がバッファリングされるわけではありません。バッファリングは添付の によって処理され streambufます。(および でfilebuf使用)の場合、入力はバッファのサイズまで可能な限り読み取り、出力はオーバーフロー時、明示的なフラッシュまたはクローズが発生したとき、またはオブジェクトが破棄されたときにバッファをフラッシュします (これは暗黙的に close を呼び出します)。ifstreamofstream

の場合coutは、破棄も終了もしないため、少し特殊です。flushが呼び出された後、少なくとも 1 回呼び出されるシステムからの保証がありますexit(これは から戻ったときに起こりますmain)。これは、main から戻る前のすべての出力がフラッシュされることを意味します。静的オブジェクトのデストラクタで使用coutしている場合でも、確実に明示的なフラッシュが必要です。

tie出力ストリームを入力ストリームにすることも可能です。cout デフォルトで関連付けられcinています。この場合、結合されたストリームから入力を試みると、出力がフラッシュされます。

通常の慣例はstd::endl、単に出力する代わりに使用すること'\n'です。std::endla を出力し'\n'、ストリームをフラッシュします。すべての出力が迅速に表示されることが非常に重要なストリームの場合、unitbuf設定できるフラグがあります。これは、ストリームが各<<オペレーターの最後にフラッシュされることを意味します。(std::cerrこれはデフォルトで設定されています。)

最後に、バッファリングの効果を見たい場合は sleep(10)、出力の後に次のようなものを置きます。出力がすぐに表示される場合は、フラッシュされています。そうでない場合は、バッファリングされており、フラッシュはsleep.

于 2012-07-09T10:12:55.143 に答える
5

次のプログラムを試してください。sleep(1)遅延(1秒)を導入するために使用されます。私はLinuxを使用しているので、sleepうまくいきます。うまくいかない場合は、このプログラムを遅らせる他の方法を試してください (単純なforループなど)。バッファリング効果が見られない場合は、バッファ サイズを増やしてみることもできます (コードのコメント行のコメントを外します)。

私の OS( Linux 3.2.0) と compiler( 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;
}
于 2012-07-09T10:03:49.360 に答える
4

次のコードを試してください。

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

于 2012-07-09T09:44:42.567 に答える