5

私はいくつかのソケットコードに取り組んでおり、ソケットでautoflush使用されている理由を理解できません。こんな感じです

my $sock = IO::Socket::Unix(Peer => $socketfilename , Type => SOCK_STREAM)

autoflush $sock 1;

との場所もあります

autoflush STDERR 1

autoflush STDOUT 1

一般的なファイルナドル用。

それは何をするためのものか?また、使わないとどうなりますか?単純な定義ではなく、理解できるように具体的な例を挙げてください。

4

3 に答える 3

9

通常、データはソケットですぐに送信されるわけではなく、特定のポイントまでバッファリングされてから、一度に送信されます。

自動フラッシュとは、データがバッファを通過してからフラッシュされることを意味し、他のデータが到着して蓄積されるのを待ってバッファに保持されることはありません。

それと同じくらい簡単です。

自動フラッシュなし:

Tick | DATA sent|Socket Buffer| DATA received
.....|..........|.............|..............
1    | XX       | XX          | (nothing)
2    | yy       | yyXX        | (nothing)
3    | ZZZ      | ZZZyyXX     | (nothing)
4    | t        | (empty)     | tZZZyyXX

自動フラッシュあり:

Tick | DATA sent | Socket Buffer | DATA received
.....|...........|...............|..............
1    | XX        | ()            | XX
2    | yy        | ()            | yy
3    | ZZZ       | ()            | ZZZ
4    | t         | ()            | t
  • ソケット バッファ サイズ: 8 文字
  • 非常に単純な例ですが、それを見た後に他の疑問を提起するかもしれません - その大部分は実装依存でもあります。さらに、バッファリングはさまざまなレベル (送信者、受信者、アプリケーションなど) で発生する可能性があります。
于 2013-02-22T12:14:17.740 に答える
7

IO :: Socket :: Unixがすでにそれを行っているので、それはまったく何もしません...

データをチャンクで送信するオーバーヘッドが少ないため、ファイルライブラリは、システムにすぐに送信するのではなく、データを蓄積してバッファに出力します。4KBまたは8KB(バージョンによって異なります)のデータが蓄積された場合にのみ、データが実際にシステムに送信されます。これは「バッファリング」と呼ばれます。

ハンドルのautoflushをtrueに設定すると、そのハンドルのバッファリングが無効になります。を呼び出すprintと、データはシステムに送信されてからprint返されます。

違いを見ます:

$ perl -e'
   STDOUT->autoflush($ARGV[0]);
   for (0..9) { print $_ x 1024; sleep 1; }
' 1
<whole bunch of 1s>
<one second later: whole bunch of 2s>
<one second later: whole bunch of 3s>
<one second later: whole bunch of 4s>
<one second later: whole bunch of 5s>
<one second later: whole bunch of 6s>
<one second later: whole bunch of 7s>
<one second later: whole bunch of 8s>
<one second later: whole bunch of 9s>

$ perl -e'
   STDOUT->autoflush($ARGV[0]);
   for (0..9) { print $_ x 1024; sleep 1; }
' 0
# Before Perl 5.14:
<four seconds later: whole bunch of 0s, 1s, 2s and 3s>
<four seconds later: whole bunch of 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>
# Perl 5.14+
<eight seconds later: whole bunch of 0s, 1s, 2s, 3s, 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>

autoflushIO :: Socket :: *によってオンになります。これは、ほとんどの場合、ソケットに必要だからです。ソケットは、インタラクティブな通信によく使用されます。リクエスト、返信、リクエスト、返信など。リクエストがバッファにスタックされた場合にどうなるか想像してみてください。あなたは永遠に返信を待っているでしょう!

于 2013-02-22T12:31:49.917 に答える
4

IO :: Handleから :

sub autoflush {
    my $old = new SelectSaver qualify($_[0], caller);
    my $prev = $|;
    $| = @_ > 1 ? $_[1] : 1;
    $prev;
}

魔法はありません。

から

$ |

ゼロ以外に設定すると、現在選択されている出力チャネルでの書き込みまたは印刷のたびに、すぐにフラッシュを強制します。デフォルトは0です(チャネルが実際にシステムによってバッファリングされているかどうかに関係なく、$|書き込みのたびにPerlに明示的にフラッシュするように要求したかどうかのみを通知します)。STDOUTは通常、出力が端末への場合はラインバッファリングされ、それ以外の場合はブロックバッファリングされます。この変数の設定は、rshでPerlプログラムを実行していて、出力が発生していることを確認したい場合など、主にパイプまたはソケットに出力する場合に役立ちます。これは入力バッファリングには影響しません。それについてはgetcを参照 してください。出力チャネルの選択方法については、selectを参照してください。IO::Handleも参照してください。

于 2013-02-23T12:20:56.013 に答える