パイプのブロッキング

パイプ上の I/O でブロッキングの挙動を見るためにちょっと実験してみた。以下、zsh で。

% cat /dev/zero | tr '\0' '\n' | cat -n | tee a | perl -MTime::HiRes=usleep -pe 'usleep 1000' > b

別の shell で以下を実行。

% (repeat 10 (sleep 10; echo $(tail -n 1 a) $(tail -n 1 b))) | awk '{print $1, $2, $1 - $2}'

結果。

9216 1024 8192
10240 1536 8704
10240 2048 8192
11264 2560 8704
11264 3072 8192
12288 3584 8704
12288 4096 8192
12288 4096 8192
13312 4608 8704
13312 5120 8192

左から、ある時点(10秒毎)での「cat -n」の出力行数、「perl -MTime::HiRes=usleep -pe 'usleep 1000'」の出力行数、その差分、となる。
まぁ、実際には各所でバッファリングが行われているのであまり正確な値ではないけれども、パイプ前段プロセスの出力がブロッキングされているのがわかるかと思う。