Perlでprint関数を実行してもすぐに画面に表示されない・・・
仕様です。print、即出力を想定してると痛い目みます。
Perlでは出力されるべき文字列はまずはメモリにバッファリングされ、決められた条件を満たした時にまとめて出力されます。
その基本的な考え方はこうです。
- ディスプレイへの出力は行バッファリング
- 改行がきたら出力
- その他のハンドルへの出力はブロックバッファリング
- 一定サイズたまったら出力
- オートフラッシュを有効化するとコマンドバッファリング
- print(、printf、write)が実行されるたびに出力
あと出力ハンドルがcloseされたとき、プログラムの終了時はもちろん出力はフラッシュされます。
じゃ見てみましょう。
ディスプレイへの出力は行バッファリング
#! /usr/bin/perl sleep 1; print "111"; sleep 1; print "222\n"; sleep 1; print "333"; sleep 1;
1秒後
$ perl line_buf.pl
2秒後
$ perl line_buf.pl 111222
3秒後
$ perl line_buf.pl 111222
4秒後
$ perl line_buf.pl 111222 333$
というわけで改行出力時にまとめて出力されてることがわかります。
その他のハンドルへの出力はブロックバッファリング
ファイル出力で確認します。
#!/usr/bin/perl open my $fh, ">>", "test.log"; for(1..9){ sleep 1; print "$_\n"; print $fh $_ x 1023 . "\n"; }
1秒後
$ tail -f test.log
2秒後
$ tail -f test.log
3秒後
$ tail -f test.log
4秒後
$ tail -f test.log 111<略>111 222<略>222 333<略>333 444<略>444
...
というわけで一定サイズ(テスト環境では4kバイト)たまったらまとめて出力されてます。
オートフラッシュを有効化するとコマンドバッファリング
上記のようなバッファリングを抑止したいときはオートフラッシュを有効化します。
そうするとprint、printf、writeを実行するごとにバッファがフラッシュされる、つまりprint、即出力が実現できます。
どうやるかは・・・長くなったので別の日記で!!