簡潔な問題の説明:
複数の (数百とします) シェル コマンドを実行できるようにしたいと考えています。それぞれが長時間実行されるプロセスを開始し、数時間または数日間ブロックされ、多くても 1 行または 2 行の出力が表示されます (このコマンドは単純です)。クラスターへのジョブの送信)。このブロックは、それぞれの結果を調査し、失敗した場合に備えて複数回再実行する可能性があるため、それぞれがいつ終了するかを正確に知ることができるので便利です。私のプログラムは、これらのプログラムの一種のコントローラーとして機能します。
for all commands in parallel {
submit_job_and_wait()
tries = 1
while ! job_was_successful and tries < 3{
resubmit_with_extra_memory_and_wait()
tries++
}
}
私が試した/調査したこと:
これまでのところ、入力の待機をブロックするだけのスレッドを送信ごとに作成するのが最善だと考えていました。かなりの数の待機中のスレッドに十分なメモリがあります。しかし、私が読んだ限りでは、perl スレッドは他の言語よりも重複プロセスに近いため、何百ものスレッドを作成することは現実的ではありません (正しいとは感じません)。
AnyEvent
やのようなさまざまなイベントループ風の協調システムもあるようCoro
ですが、これらは非同期ライブラリに依存する必要があるようです。そうしないと、実際には何も同時に実行できません。それを使って複数のシェルコマンドを作成する方法がわかりません。を使用してみましAnyEvent::Util::run_cmd
たが、複数のコマンドを送信した後、それらを待機する順序を指定する必要があります。各提出にどれくらいの時間がかかるかは前もってわからないので、recv
時々非常に不運に見舞われなければなりません. これは実際には平行ではありません。
my $cv1 = run_cmd("qsub -sync y 'sleep $RANDOM'");
my $cv2 = run_cmd("qsub -sync y 'sleep $RANDOM'");
# Now should I $cv1->recv first or $cv2->recv? Who knows!
# Out of 100 submissions, I may have to wait on the longest one before processing any.
AnyEvent とその友人に対する私の理解が間違っている可能性があるので、そうであれば訂正してください。:)
もう 1 つのオプションは、ジョブの送信を非ブロッキング形式で実行し、その完了をプロセスに通知することですが、これを達成して異なるマシン間で調整するために必要なプロセス間通信は、私を少し圧倒します。それに頼る前に、ローカルな解決策を見つけたいと思っています。
私が見落とした解決策はありますか?