[bash]複数処理をバックグラウンドで並列実行する

bash

複数の重いタスクを同時に処理したいとき、並列実行は便利ですがあまり頻繁にも使わなかったので、改めて整理しました。
並列実行できればスクリプトやオペレーションなど効率的になるので、1つづつまとめていければと。
最終的にはワンライナーのコマンドも紹介します。だれかの役に立てばなによりです。

基本からおさらい

コマンドの末尾に「&」を付けることで、そのコマンドをバックグラウンドで実行することができます。複数ターミナル開いて別々にやらせればいいのですが、ターミナルも開きすぎると管理が煩雑になり、誤操作の原因にもなります。
バックグラウンド実行させることで、コマンド実行中でもターミナルを使い続けることが可能になるので覚えてて損はないはず。

ステップ1: 基本的なバックグラウンド処理

まずはおさらいがてら。sleepコマンドをバックグラウンドで実行します。

ステップ2: 複数のコマンドを並列に実行

複数のコマンドをバックグラウンドで実行することで、並列処理が可能です。例えば、複数のsleepコマンドを同時に実行してみましょう。

このように、2つのコマンドが同時に実行され、より効率的にタスクを処理できます。

ステップ3: waitコマンドで同期を取る

並列処理後に全てのプロセスが終了するまで待ちたい場合は、waitコマンドを使用します。waitを使うことで、バックグラウンドで実行されている全てのプロセスが終了するのを待つことができます。

この例では、sleep 10sleep 5が完了した後に、「All processes are done!」が表示されます。

ステップ4: 応用例 – ファイル処理の並列実行

例えば、大量の画像ファイルを一気に変換したいときには、以下のように並列で処理を行うことができます。

このスクリプトでは、ディレクトリ内の全ての.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

コメント

  1. Twicsy より:

    Hi there to every , because I am actually eager of reading this website’s post to be updated daily.
    It carries nice information.

  2. It’s very straightforward to find out any topic on web as compared to books,
    as I found this post at this website.

タイトルとURLをコピーしました