#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf("If I had more time, \n");
write(STDOUT_FILENO, "I would have written you a shorter letter.\n", 43);
return 0;
}
私は読んだ
I / O処理関数(
stdio
ライブラリ関数)とシステムコールは、パフォーマンスを向上させるためにバッファリング操作を実行します。この関数はユーザー空間のprintf(3)
バッファを使用します。stdio
また、カーネルはI / Oをバッファリングするため、システムコールごとにディスクに書き込む必要はありません。デフォルトでは、出力ファイルが端末の場合、printf(3)
この関数の書き込みline-buffered
とstdio
使用は次のとおりです。ラインバッファたとえば、stdout
改行文字が見つかった場合、'\n'
バッファは次にフラッシュされます。バッファキャッシュ。ただし、端末でない場合、つまり標準出力がディスクファイルにリダイレクトされると、バッファにスペースがなくなったとき(またはファイルストリームが閉じられたとき)にのみコンテンツがフラッシュされます。上記のプログラムの標準出力が端末の場合、最初の呼び出しはprintf
そのバッファを次にフラッシュします。カーネルバッファ(バッファキャッシュ)改行文字が見つかると、'\n'
上記の文と同じ順序で出力されます。ただし、出力がディスクファイルにリダイレクトされると、バッファはフラッシュされず、システムコールのstdio
内容がwrite(2)
カーネルバッファに最初に到達するため、呼び出しの内容の前にディスクにフラッシュされますprintf
。
ターミナルはいつ頃stdout
ですか?
If I had more time,
I would have written you a shorter letter.
stdout
ディスクファイルはいつですか?
I would have written you a shorter letter.
If I had more time,
しかし、私の質問は、端末に送信するのかディスクファイルに送信するのかをどうやってstdio library functions
知ることができるのかということです。stdout
答え1
printf
(私の特定のlibc)は、内部的にnewfstatat()
stdoutファイル記述子(たとえば1)からシステムコールを実行します。
入力している通常のファイルまたは文字デバイス(擬似端末など)の場合、カーネルはこれらのst_mode
フィールドを入力します。S_IFREG
s_IFCHR
私が見つけた方法:
gcc -o foo foo.c # compile your program
strace -o file.strace ./foo > tempfile
strace -o term.strace ./foo
diff *.strace #and look for things towards the end that concern the 1 file descriptor