Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

実行環境

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がすごすぎて生きるのがつらい

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした