今日、stdout が端末に設定されている場合はライン バッファリングされ、さまざまな場合にバッファリングされることを知りました。したがって、通常の状況では、'\n' を終了せずに printf() を使用すると、バッファがいっぱいになったときにのみ画面に出力されます。このバッファのサイズを取得する方法、これはどれくらいの大きさですか?
4 に答える
The actual size is defined by the individual implementation; the standard doesn't mandate a minimum size (based on what I've been able to find, anyway). Don't have a clue on how you'd determine the size of the buffer.
Edit
7.19.3 Files
...
3 When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via thesetbuf
andsetvbuf
functions.
Emphasis added.
"Implementation-defined" is not a euphemism for "I don't know", it's simply a statement that the language standard explicitly leaves it up to the implementation to define the behavior.
And having said that, there is a non-programmatic way to find out; consult the documentation for your compiler. "Implementation-defined" also means that the implementation must document the behavior:
3.4.1
1 implementation-defined behavior
unspecified behavior where each implementation documents how the choice is made
2 EXAMPLE An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.
デフォルトのパイプサイズ 64K に対してパイプを作成するときの Linux が使用されます。/proc/sys/fs/pipe-max-size には、パイプの最大サイズが存在します。デフォルトでは 1048576 が一般的です。
glibc のデフォルトのファイル バッファ用。65536 バイトが妥当と思われます。ただし、glibc のソース ツリーから grep を実行すると、次のように確認できます。
それによって、元の質問に答えられるかもしれないし、答えられないかもしれません。1 分間の努力で、最良の推定値は 8 キロバイトです。
単なる行バッファリングには 8K で十分です。ただし、64K と比較して 1 行以上のバッファー出力の場合。8K は効率的ではありません。デフォルトのパイプ サイズには 64K が使用され、それ以上のパイプ サイズが予期されず、より大きなパイプ サイズが明示的に設定されていない場合は、stdio バッファーに 64K が推奨されるためです。
パフォーマンスが必要な場合、わずかな 8K バッファでは十分ではありません。fcntl(pipefd,F_SETPIPE_SZ,1048576) により、パイプのサイズを増やすことができます。setvbuf (stdout,buffer,_IOFBF,1048576) により、stdio が提供するファイル バッファを置き換えることができます。パイプを使用しない場合、パイプのサイズは関係ありません。ただし、2 つのプロセス間でデータがパイプ処理される場合は、パイプ サイズを大きくすることでパフォーマンスが向上する可能性があります。そうしないと、最小のバッファーまたは最小のパイプによってボトルネックが発生します。
読み取りも行う場合は、stdio によるより大きなバッファーによって、必要な読み取り関数の呼び出しが少なくなる可能性があります。「かもしれない」という言葉によって、重要な考慮事項が示唆されます。単一の読み取り関数呼び出しによる単一の書き込み関数呼び出しによって提供されるように、多くのデータを読み取ることができます。読み取り関数の呼び出しによって、要求されたよりも少ないバイト数で返されることが期待できます。追加の読み取り関数呼び出しにより、追加のバイトが取得される場合があります。
データ行の書き込み用。by stdio overkill が提供されます。ただし、stdio ラインによるバッファ出力は可能です。一部のシナリオでは、ライン バッファ出力が不可欠です。proc 仮想ファイル システムが提供するファイルに書き込む場合、または sys 仮想ファイル システムが提供するファイルに書き込む場合は、単一の書き込みバッファーに改行バイトを含める必要があります。2 回目の書き込みが使用されると、予期しない結果になる可能性があります。
読み書きと stdio が混在している場合、注意事項があります。write 関数呼び出しの前に、fflush 関数呼び出しが必要です。stderr はバッファリングされていないためです。stderr の場合、fflush 関数の呼び出しは必要ありません。読み取りによって、予想よりも少ないバイト数が提供される場合があります。stdio によって、前のバイトが既にバッファリングされている可能性があります。
unistd と stdio I/O を混在させないことは良いアドバイスですが、しばしば無視されます。バッファリングされた入力を混在させることは合理的ではありません。バッファリングされていない入力の混合が可能です。バッファリングされた出力の混合はもっともらしいです。
stdio によってバッファリングされた IO の利便性が提供されます。stdio がなければ、バッファリングされた IO が可能です。ただし、コードには追加のバイトが必要です。十分なサイズのバッファーが活用されている場合。stdio が提供する出力関数と比較。書き込み関数の呼び出しが必ずしも遅くなるわけではありません。
ただし、パイプが含まれていない場合は、関数 mmap によって優れた IO を提供できます。mmap によるパイプでは、エラーは返されません。ただし、アドレス空間ではデータは提供されません。lseek によるパイプでは、エラーが発生します。
最後に man 3 setvbuf による良い例が提供されています。スタック上にバッファが割り当てられている場合、リターンの前に fclose 関数の呼び出しを省略してはなりません。
実際の質問は、「C では、stdout バッファーのサイズは?」というものでした。8192年までには、それだけのことが答えられるかもしれません。
この質問に遭遇した人は、バッファーの入出力効率に関する好奇心を持っているかもしれません。いくつかの調査によって、目標は暗黙のうちに達成されます。簡潔な応答の優先設定により、パイプ サイズの重要性とバッファー サイズの重要性、および mmap は説明されません。この回答は説明します。
here are some pretty interesting answers on a similar question.
on a linux system you can view buffer sizes from different functions, including ulimit
.
Also the header files limits.h
and pipe.h
should contain that kind of info.
バッファなしに設定するか、単にフラッシュすることができます。
Cランタイムが通常あなたといくつかの例のためにそれをフラッシュするとき、これはいくつかのまともな情報を持っているようです. これを見てください。