1

正確な数と正確な数を事前に知らなくても、一連のコマンドを実行できるようにしたいと考えています。これらのコマンドは通常、それぞれ数時間または数日かかる計算です。コマンドはクラスターで実行され、ノードを事前に予約する必要があるため、事後的にコマンドのリストを変更する方法が必要です。

(それが何であれ)(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」を使用することもできますが、それでは問題は解決しません。

4

3 に答える 3

2

あなたの問題にはやり過ぎかもしれませんが、そのためにBoscoを使用できます。

それが行うことは、クラスターからいくつかのリソースを要求することです (多くのジョブ スケジューラがサポートされています)。ラップトップでローカル キュー システムが実行されているため、ローカルでジョブを送信でき、それらはクラスターの割り当てに「グライド」されます。

ローカルの Bosco インストールに必要な数のタスクをサブミットすることができ、割り当てられた CPU の数を考慮して、クラスターで実際にそれらを実行します。

1 つのタスクを忘れた場合は、ローカルの Bosco インストールにもう 1 つ送信するだけで、それが処理されます。

于 2014-08-05T20:00:12.600 に答える
1
#!/bin/bash

exec 4< <(exec tail -n+0 -f command-list.txt)
TAIL_PID=$!
exec 5> >(exec parallel -j2 'sleep 1 && echo {}')

while IFS= read -ru 4 __; do
    if [[ $__ == EXIT ]]; then
        exec 4<&- 5>&-
        kill -s SIGHUP "$TAIL_PID"
        break
    fi
    echo "$__" >&5
done
于 2014-08-05T18:22:35.987 に答える
1

GNU のバグparallelの可能性とtail.

GNU Parallel では、次のように変更します。

        # Ignore the rest of input file                                                                   
        while (<$fh>) {}                                                                                 

に:

        # Ignore the rest of input file                                                                   
        close $fh;

次に使用します。

tail -n+0 -f command-list.txt | (parallel -j2 --eof=EXIT {}; echo Parallel is now done; (seq 1000 >> command-list.txt &);echo Done appending dummy data)

次で終了します。

echo pwd >> command-list.txt
echo "EXIT" >> command-list.txt

ご覧のように綺麗に仕上がっていますねparallel~ぶら下がっているのですが、仕上がった後に作るtailファイナルは、完成したことを理解させてくれます。seqparalleltail

tailは、FreeBSD、OpenBSD、および Debian GNU/Linux で同じ動作をするため、動作が最適ではありませんが、バグとは見なされない可能性があります。

于 2014-08-05T23:21:02.207 に答える