parallel-1.0.0
名称 | Parallel Execution Control Tool(並列実行制御ツール) |
---|---|
バージョン | 1.0.0 (1.00.0000.20210721) リリースノート |
開発環境 | Linux 3.10.0-1160.15.2.el7.x86_64 (CentOS 7.9.2009) ※ 上記以外での動作確認は行っておりません。 |
開発者 | Tetsu Ohta TSUJIMOTO @ U-PRIMO (https://www.u-primo.org) |
コンセプト
- ごちゃごちゃしたお作法は要らない
- 大量のコマンドラインを投げたら適当に並列実行してくれれば良い
概要
複数のコマンドを単一マシン内で同時実行するだけのシンプルなツールです。 単体で数十秒以上かかる重めの処理を大量に実行する際に効果を発揮します。
処理内容(コマンドライン)を標準入力から順次受け取り、それをバックグラウンドで開始し、本ツールで実行中のジョブ数がプロセッサ数以下になるように制御します。 オプションで同時実行数をプロセッサ数以下に制限することができます。 マシンの負荷状況を考慮して調整したり、並列化されているプログラムを含んでいる場合などに調整すると良いでしょう。
より高度な処理を行う場合は、GNU Parallel 等のほうが良いでしょう。
使用方法
parallel [オプション]
オプション
オプション
-i <interval> | ジョブの監視間隔を秒で指定する。デフォルト値は3秒。 |
-n <concurrency> | 同時に実行するジョブ数を指定する。デフォルト値はプロセッサ数。 |
-q | 本ツールのログ出力を抑制する。 |
使用例 (1)
実行したいコマンドラインをファイルに書いておき、本ツールに投入する。
※ 動作を分かりやすくするため、監視間隔を0秒に設定しています。parallel() の()内はプロセスIDです。
同時実行数を2つに制限して実行する。
※ 動作を分かりやすくするため、監視間隔を0秒に設定しています。parallel() の()内はプロセスIDです。
$ cat test.txt
24コアのマシンで3つのジョブが投入されたので、全てのジョブが同時に実行されている。
sleep 10
sleep 20
sleep 30
$
$ parallel -i 0 < test.txt
[2021-07-21 12:01:00] localhost: parallel(1357): started
[2021-07-21 12:01:00] localhost: parallel(1357): concurrency=24, interval=0
[2021-07-21 12:01:00] localhost: parallel(1357): [1] sleep 10
[2021-07-21 12:01:00] localhost: parallel(1357): [2] sleep 20
[2021-07-21 12:01:00] localhost: parallel(1357): [3] sleep 30
[2021-07-21 12:01:30] localhost: parallel(1357): finished in 0:00:30
$
同時実行数を2つに制限して実行する。
$ parallel -i 0 -n 2 < test.txt
最初に2つのジョブが実行され、ジョブが1つ終了した時点で3つ目のジョブが開始されている。
[2021-07-21 12:02:00] localhost: parallel(2468): started
[2021-07-21 12:02:00] localhost: parallel(2468): concurrency=2, interval=0
[2021-07-21 12:02:00] localhost: parallel(2468): [1] sleep 10
[2021-07-21 12:02:00] localhost: parallel(2468): [2] sleep 20
[2021-07-21 12:02:10] localhost: parallel(2468): [3] sleep 30
[2021-07-21 12:02:40] localhost: parallel(2468): finished in 0:00:40
$
使用例 (2)
シェルスクリプトでコマンドラインを生成し、直接本ツールに投入する。
$ cat test.sh
シンプルなスクリプトであれば、本来の処理部分(本例では sleep コマンド)に echo を追加してコマンドラインそのものを出力し、ループ全体の出力をパイプで parallel に渡すように変更するだけで、簡単に並列実行を制御できます。
ただし、メッセージ等のコマンドライン以外の出力がある場合は、それを抑制するか標準エラー出力に変更する必要があります。
#!/bin/sh
for i in `seq 10 10 1000`
do
echo sleep $i
done | parallel
$
$ sh test.sh
[2021-07-21 12:03:00] localhost: parallel(3579): started
[2021-07-21 12:03:00] localhost: parallel(3579): concurrency=24, interval=3
[2021-07-21 12:03:00] localhost: parallel(3579): [1] sleep 10
[2021-07-21 12:03:00] localhost: parallel(3579): [2] sleep 20
[2021-07-21 12:03:00] localhost: parallel(3579): [3] sleep 30
[2021-07-21 12:03:00] localhost: parallel(3579): [4] sleep 40
[2021-07-21 12:03:00] localhost: parallel(3579): [5] sleep 50
使用例 (3)
単独のシェルスクリプトで、自分自身を並列実行する。
例えば、下記のように i = 10, 20, 30, …, 1000 に応じて複雑な処理をするスクリプトがあったとします。
並列実行される複雑な処理に共通する設定内容は、if 文の外に記述すると良いでしょう。 中間ファイルを出力する場合は、ファイル名が重複しないように注意してください。
例えば、下記のように i = 10, 20, 30, …, 1000 に応じて複雑な処理をするスクリプトがあったとします。
$ cat test2.sh
これを下記のように書き換えます。
#!/bin/sh
前処理
for i in `seq 10 10 1000`
do
複雑な処理
done
後処理
$ cat test2.sh
test2.sh を(引数なしで)実行すると冒頭の if 文に入り、「sh test2.sh 10」「sh test2.sh 20」「sh test2.sh 30」…「sh test2.sh 1000」というコマンドラインを生成し、parallel に渡します。
parallel から引数ありで実行された test2.sh は冒頭の if 文をすり抜け、引数から必要な情報を受け取って処理を開始します。
このように、比較的軽微な修正で既存のシェルスクリプトを並列実行することができます。
また、「done #| parallel」の様にしてコメントアウトすれば、parallel に対して投入するコマンドラインを事前に確認することができます。
#!/bin/sh
if [ $# = 0 ]; then
前処理
for i in `seq 10 10 1000`
do
echo sh $0 $i
done | parallel
後処理
exit
fi
i=$1
複雑な処理
並列実行される複雑な処理に共通する設定内容は、if 文の外に記述すると良いでしょう。 中間ファイルを出力する場合は、ファイル名が重複しないように注意してください。
カスタマイズ
本ツールは単独のシェルスクリプトでできています。
メイン処理の部分は非常に短く、主な処理は関数化されていますので、容易に手を入れることができるかと思います。
ご不明な点はサポートまでお問い合わせください。