通常、Unixのパイプは2つのコマンドを接続し、最初のコマンドの出力を2番目のコマンドの入力として使用するために使用されます。しかし最近、私はパイプを使って複数のコマンドを並列に実行するというアイデアを思いつきました(これは新しいものではないかもしれませんが、インターネット検索ではあまり見つかりませんでした)。
command1 | command2
これは並列に呼び出されますcommand1
。command2
command2
標準入力から読み取らないcommand1
場合、または標準出力に書き込まない場合t。これを説明するための最小限の例(対話型シェルで実行してください)
ls . -R 1>&2|ls . -R
私の質問は、パイプを使用してこのように2つのコマンドを並列に実行することに欠点がありますか?このアイデアに私が逃した部分はありますか?
よろしくお願いします。
答え1
コマンドパイプラインはすでに並列に実行されています。使用コマンド:
command1 | command2
command1
どちらもcommand2
始まりました。予約されていてcommand2
パイプが空の場合、読み取りを待つのはブロックされます。command1
パイプに書き込もうとしていますが、パイプがいっぱいになると書き込むcommand1
スペースができるまでブロックされます。それ以外の場合command1
と両方がcommand2
並列に実行され、パイプに書き込まれ、パイプから読み取られます。
答え2
欠点があります。
- 見えない出力
command1
command2
出力を読み取らないと、command1
後者は特定の量の出力を書き込んで停止します(4Kを見ましたが、実験によると、少なくともPythonプロセスの場合、制限は約58Kです。以下を参照)。これは使用されるランタイムによって異なりますcommand1
。command2
以前に停止してcommand1
標準command1
出力に書き込んだ場合は、次のようになります。[Errno 32] Broken pipe
実験:
ガイドライン1#! /usr/bin/python3
import sys,time
for i in range(64):
print ("*"*1023,file=sys.stdout)
print ("cmd1 here (%d)" % i,file=sys.stderr)
time.sleep(.1)
print ("cmd1 exiting",file=sys.stderr)
ガイドライン2
#! /usr/bin/python3
import sys,time
for i in range(16):
print ("cmd2 here (%d)" % i,file=sys.stderr)
time.sleep(1)
print ("cmd2 exiting",file=sys.stderr)
ランニング:
./cmd1 | ./cmd2
あなたは見ることができます:
cmd1
繰り返し58で停止します(cmd2は出力から何も読み取らないためです)。cmd1
終了時にcmd2衝突(壊れたパイプ)
はい、たぶん効果があるかもしれません。おそらく。