正確な数と正確な数を事前に知らなくても、一連のコマンドを実行できるようにしたいと考えています。これらのコマンドは通常、それぞれ数時間または数日かかる計算です。コマンドはクラスターで実行され、ノードを事前に予約する必要があるため、事後的にコマンドのリストを変更する方法が必要です。
(それが何であれ)(i)実行中にコマンドを読み取り、プロセッサが解放されるまでコマンドを起動し続け、(ii)コマンドが実行されなくなったら終了することを望みます。
これを達成する最も簡単な方法は何ですか?
編集:これは機能します(GNUパラレルで)
まず、回答で示唆されているように、変更parallel
(例: /usr/bin/parallel
)、変更
# Ignore the rest of input file
while (<$fh>) {}
に
# Ignore the rest of input file
close $fh;
次に、次のようにテストします。
seq 10 > test; tail -f test | parallel -uE EXIT 'echo {}'
ノート
- 「-u」は「グループ解除」用であり、すべての行が読み込まれ、実行され、表示され、procs が利用可能になります。
- "-E EXIT" は kill できるようにするためのものです: EXIT を書いた後、'tail -f' が死ぬように別の (任意の) 文字列を書かなければなりません。(上記の変更を行わないと、パラレルはストリームを開いたままにし、これは機能しません)
- ストリームが空で CPU がアイドル状態の場合は終了しません
if(items_processed>0 && nprocs_running==0) exit
。その後、テールを殺すという問題がまだありますが、これは、入力ファイルに定期的に偽の書き込みを行うことで、醜い方法でハッキングされる可能性があります。
私が試したこと
私が考えることができる最も単純な構文は、GNU parallel を使用して次のようなものになります。
parallel < command-list.txt
[...some time later...]
echo "this-command-I-forgot" >> command-list.txt
これはうまく機能します...ただし、コマンドの数がCPUの数よりも少ない場合(これは一般的です。16 cpuマシンで10プロセスから開始する場合があります)、EOFが発生し、ストリームを閉じると表示されますさらにコマンドを追加する方法はありません。したがって、実行中のコマンドが終了するたびに終了します。
EOFの問題を回避するために、テールでストリームをたどることができると思いました
tail -n+0 -f command-list.txt | parallel --eof=EXIT
たとえば、次の簡単なテストのように:
seq 10 > command-list.txt
tail -n+0 -f command-list.txt | parallel -j2 --eof=EXIT 'sleep 1 && echo {}'
echo "this-command-I-forgot" >> command-list.txt
これは非常に近くなり、コマンドを追加できますが、ファイルは閉じません。ただし、最後まで到達せず、「EXIT」を読み取っても停止せず、代わりにハングします。理由はわかりません。ブロックで読み込んでいるのかもしれません(??) また、すべてのプロセスが終了し、ファイルに何もする必要がなくなっても停止しません。
(これは、回答で提案されているバグに関連している可能性があるので編集してください)
または、「wait PID」を使用して各 CPU のいくつかの子プロセスを起動することを想像できますが、それは複雑すぎるように見えます。さらに、これはまさに GNU/parallel が行うべきことのようです。
助けや提案をありがとう!
ここの コメントに基づいて編集します。これは少なくとも終了しますが、最初にキーワード「EXIT」が必要です。
sh -c 'tail -n+0 -f command-list.txt | { sed "/EXIT/Q" && kill -9 $$ ;}' | parallel -j2 'sleep 1 && echo {}'
このスレッドで提案されているように、「parallel -j2」の代わりに「xargs -P2」を使用することもできますが、それでは問題は解決しません。