複数の重いタスクを同時に処理したいとき、並列実行は便利ですがあまり頻繁にも使わなかったので、改めて整理しました。
並列実行できればスクリプトやオペレーションなど効率的になるので、1つづつまとめていければと。
最終的にはワンライナーのコマンドも紹介します。だれかの役に立てばなによりです。
- 目次 -
基本からおさらい
コマンドの末尾に「&
」を付けることで、そのコマンドをバックグラウンドで実行することができます。複数ターミナル開いて別々にやらせればいいのですが、ターミナルも開きすぎると管理が煩雑になり、誤操作の原因にもなります。
バックグラウンド実行させることで、コマンド実行中でもターミナルを使い続けることが可能になるので覚えてて損はないはず。
ステップ1: 基本的なバックグラウンド処理
まずはおさらいがてら。sleep
コマンドをバックグラウンドで実行します。
sleep 10 &
ステップ2: 複数のコマンドを並列に実行
複数のコマンドをバックグラウンドで実行することで、並列処理が可能です。例えば、複数のsleep
コマンドを同時に実行してみましょう。
sleep 10 &
sleep 5 &
このように、2つのコマンドが同時に実行され、より効率的にタスクを処理できます。
ステップ3: waitコマンドで同期を取る
並列処理後に全てのプロセスが終了するまで待ちたい場合は、wait
コマンドを使用します。wait
を使うことで、バックグラウンドで実行されている全てのプロセスが終了するのを待つことができます。
sleep 10 &
sleep 5 &
wait
echo "All processes are done!"
この例では、sleep 10
とsleep 5
が完了した後に、「All processes are done!」が表示されます。
ステップ4: 応用例 – ファイル処理の並列実行
例えば、大量の画像ファイルを一気に変換したいときには、以下のように並列で処理を行うことができます。
for file in *.jpg; do
convert "$file" "${file%.jpg}.png" &
done
wait
echo "All images have been converted."
このスクリプトでは、ディレクトリ内の全ての.jpg
ファイルを同時に.png
に変換し、全ての変換が終わった後にメッセージを表示します。
番外編:ワンライナーでの使用方法/使用例
思い込みもあり時間がかかった部分です。
処理時間が長いスクリプトを複数同時実行し、かつスクリプトのリターンコードを取りたいがために「;」でコマンドを連結させたいようとした時につまづきました。
<処理1>と<処理2>を連結(「;」)させる。これを一まとまりとして、複数処理をfor文で回して、かつバックグラウンドで並列実行させる記述方法。
Concatenate <process 1> and <process 2> using a semicolon (;). Treat this as a single unit, iterate over multiple processes with a for
loop, and execute them in parallel in the background.
This describes how to chain together commands and run them concurrently using a for
loop in Bash, ensuring they all execute simultaneously in the background.
#とりあえず結論(成功例)です。
for <変数> in ; do ( <処理1> ; <処理2> ) & done
#使用例(sample)
Sleep後リターンコードを取得(Sleep 間隔は3,5,8秒と別々)、このまとまりを並列実行させる場合。
Obtain the return code after executing sleep (with intervals of 3, 5, and 8 seconds respectively), and execute this set in parallel.
for i in 3 5 8 ; do ( sleep ${i} ; echo $? ) & done
■処理のイメージ
【ざっくり解説、つまづいたところ】
ひとまとまりの処理をバックグラウンド実行させるため、一連の処理を「( )」で括り、後ろに「&」を加える。ここまではよかった
( <処理1> ; <処理2> ) &
これをワンライナーのfor文で回すため、下のコマンドを作ったところ、「予期しないトークン ”;” 周辺に構文エラーがあります」でエラーになった。
■これだとエラーになる
for i in ; do ( <処理1> ; <処理2> ) & ; done
それではとバックグランド実行「&」を除くと問題なく実行されたがバックグラウンドでの実行にはならなかった。
■これはエラーにならないけどバックグラウンド実行されない
for i in ; do ( <処理1> ; <処理2> ) ; done
結局「done」の前の「;」を除いて「&」にすることでエラーがなくなり、想定していた動作をしてくれました。
for i in ; do ( <処理1> ; <処理2> ) & done
コメント
Hi there to every , because I am actually eager of reading this website’s post to be updated daily.
It carries nice information.
It’s very straightforward to find out any topic on web as compared to books,
as I found this post at this website.