パイプラインに固執して読み取りと書き込みの速度を分離できるユーティリティはありますか?
$ producer | buf | consumer
基本的に、buf
可能な限り高速に入力を読み取り、メモリに保存して、可能な限り高速で実行しconsumer
ながら甘い時間を過ごすことができるユーティリティが必要ですproducer
。
stdbuf
ツールがあるように思われるsize
パラメータ。それが動作するかどうかはわかりません。
パイプラインに固執して読み取りと書き込みの速度を分離できるユーティリティはありますか?
$ producer | buf | consumer
基本的に、buf
可能な限り高速に入力を読み取り、メモリに保存して、可能な限り高速で実行しconsumer
ながら甘い時間を過ごすことができるユーティリティが必要ですproducer
。
stdbuf
ツールがあるように思われるsize
パラメータ。それが動作するかどうかはわかりません。
回答:
pv
(パイプビューア)ユーティリティは、(でこれを行うことができ-B
ますが、経過報告与え含め、より多くのオプション)と。
producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2
)、これにより再びスローダウンが発生する可能性があります。
pv
何百回も使用しましたが、これを知りませんでした。とても素晴らしい、ありがとう!
pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null
- pv
両端の両方がスムーズであると期待しています(ただし、どちらも1GB先です)。それはとは異なり、このように動作しませんmbuffer
あなたが使用することができますdd
:
producer | dd obs=64K | consumer
すべてのUNIXで利用可能です。
pv
を使用する場合は+1を使用しますが、おそらく使用するほうがよいでしょう(進行状況を表示します)。
dd
一度に1つのブロックしか保存しないように見えるため、ブロックサイズを生成するのにかかる時間だけすべてを遅延させます。私が間違っている場合は修正してください。また、このバッファリングを無制限のサイズに拡張したり、ブロックサイズに入力したものだけを拡張したりできますか?
これは基本的に否定的な答えです。これは、どちらもそれを表示されないdd
、またmbuffer
、またしてもpv
動作しますプロデューサーによって生成されたデータの割合が多くを変えることができれば、特に、すべてのケースです。以下にいくつかのテストケースを示します。コマンドを入力した後、約10秒間待ってから入力します>
(データの最後に移動する、つまり入力の終わりを待ちます)。
zsh -c 'echo foo0; sleep 3; \
printf "Line %060d\n" {1..123456}; \
echo foo1; sleep 5; \
echo foo2' | dd bs=64K | less
ここでは、を入力した後>
、5秒間待機する必要がありsleep 5
ます。つまり、プロデューサー(zshスクリプト)はの前にブロックされています。bs
サイズをたとえば32Mに増やしても動作は変わりませんが、32MBのバッファーは十分に大きくなります。これはdd
、入力を続行するのではなく、出力をブロックするためだと思われます。oflag=nonblock
これはデータを破棄するため、使用は解決策ではありません。
zsh -c 'echo foo0; sleep 3; \
printf "Line %060d\n" {1..123456}; \
echo foo1; sleep 5; \
echo foo2' | mbuffer -q | less
でmbuffer
、問題は、最初の行(foo0)がすぐに表示されないということです。入力時に行バッファリングを有効にするオプションはないようです。
zsh -c 'echo foo0; sleep 3; \
printf "Line %060d\n" {1..123456}; \
echo foo1; sleep 5; \
echo foo2' | pv -q -B 32m | less
ではpv
、動作がに似ていますdd
。さらに悪いことに、端末からless
入力を受け取ることができない場合があるため、端末に対して間違った動作をすると思われます。たとえば、で終了することはできませんq
。
非標準の移動:ソケットバッファーを使用します。
例:
# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
i: 468MB 0:00:16 [ 129kB/s] [ <=> ]
o: 1.56MB 0:00:16 [ 101kB/s] [ <=> ]
このために、buffered_pipelineとmapopentounixsocketの 2つの追加ツールを実装しました
$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
1: 13.4MB 0:00:40 [ 103kB/s] [ <=> ]
2: 3.91MB 0:00:40 [ 100kB/s] [ <=> ]