LoginSignup
230
204

More than 5 years have passed since last update.

シェルスクリプトで単純に並列実行・直列実行を行う

Last updated at Posted at 2016-06-29

実行環境

MacのBash

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.

単純な直列実行

$ sleep 2
$ sleep 4
$ sleep 1
$ sleep 4 # 合計で2+4+1+4=11秒かかる

バックグラウンドプロセスを用いた単純な並列実行

$ sleep 2 & # コマンド末尾に&をつけて呼び出すとバックグラウンドプロセスになり、並列で実行される
$ sleep 4 &
$ sleep 1 &
$ sleep 4 &
$ wait # 上記のバックグラウンドプロセスたちを待機。もっともかかるもので4秒なため、合計で4秒かかる
[1] 38498
[2] 38499
[3] 38500
[4] 38501
[3]  - 38500 done       sleep 1  # 1秒後([1]のプロセスより先に終了)
[1]    38498 done       sleep 2  # 2秒後
[4]  + 38501 done       sleep 4  # 4秒後([2]のプロセスとほぼ同時に終了)
[2]  + 38499 done       sleep 4  # 4秒後([4]のプロセスとほぼ同時に終了)

バックグラウンドプロセスを用いて直列実行がしたい場合

echo "hogehoge.shを実行します"
./hogehoge.sh & # バックグラウンドプロセスとして起動
wait $! # $!で直前のバックグラウンドのプロセスIDが得られるため、それが終わるまで待機
echo $? # hogehoge.shの終了ステータス
echo "fugafuga.shを実行します"
./fugafuga.sh & # hogehoge.shが終了してから実行されるバックグラウンドプロセス
wait $!
echo $? # fugafuga.shの終了ステータス

そもそもバックグラウンドプロセスにしている時点で直列実行する必要がないだろうが、上記のようにプロセスIDを$!で取得し指定すれば可能

xargsを用いた並列実行

xargsに-P (--max-procs)というオプションがあって、それで指定してやれば指定のプロセス数まで並列実行してくれます。
xargs -P (並列プロセス数) (実行したいコマンド)だけなので簡単。

参照: xargs を使ってカジュアルに並列処理

普通にxargsで実行(上から順に実行される)

$ time seq 1 5 | xargs -I ZZ -P 1 sleep 1
seq 1 5  0.00s user 0.00s system 49% cpu 0.006 total
xargs -I ZZ -P 1 sleep 1  0.01s user 0.01s system 0% cpu 5.034 total # 5.034秒かかった

1秒かかるプロセスを5つ実行すると5秒かかる

並列実行(-P 5 で5プロセスまでの並列実行)

$ time seq 1 5 | xargs -I ZZ -P 5 sleep 1
seq 1 5  0.00s user 0.00s system 60% cpu 0.009 total
xargs -I ZZ -P 5 sleep 1  0.01s user 0.01s system 1% cpu 1.015 total # 1.015秒かかった

5プロセスまで並行実行する設定で
1秒かかるプロセスを5つ実行すると1秒かかる

$ time seq 1 7 | xargs -I ZZ -P 5 sleep 1
seq 1 7  0.00s user 0.00s system 65% cpu 0.006 total
xargs -I ZZ -P 5 sleep 1  0.01s user 0.02s system 1% cpu 2.032 total # 2.032秒かかった

5プロセスまで並行実行する設定で
1秒かかるプロセスを7つ実行すると2秒かかる

他の手法

GNU Parallelというものもあるらしい。とりあえず brew install parallel でインストールすることが出来た。
xargsの例を真似て

time seq 1 100 | parallel -j 100%  sleep 1

ということもしてみた。こちらのほうが高機能そう。

参照: GNU Parallelがすごすぎて生きるのがつらい

230
204
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
230
204