【バッチスクリプト】複数のバッチスクリプトを並列実行する処理【STARTコマンド】


いつもお世話になっております。
RfromLです。

今回は複数のバッチスクリプトを並列実行するバッチスクリプトについてです。

1.はじめに

以前「【バッチスクリプト】複数のバッチスクリプトを連続実行(逐次実行)する処理」について紹介しましたが今回は「START」コマンドを使用して複数のバッチスクリプトを並列実行(同時実行)するバッチスクリプトについてです。

例として、異なる処理を行うバッチスクリプトが3つあったとします。

・バッチ①.bat
・バッチ②.bat
・バッチ③.bat

各処理はお互いが関係の無い処理なので、以下イメージ図のように同時に実行されても問題ないものとします。

バッチスクリプトからバッチスクリプト実行に使用するコマンドは「START」コマンドです。


[コード]

START バッチ①.bat
START バッチ②.bat
START バッチ③.bat


【CALLコマンドとの違い】
CALLコマンドでバッチスクリプトを実行した場合は、呼び元のバッチスクリプトは実行先のバッチスクリプトが終了してから次のコマンドへ進むようになっていますが、STARTコマンド(オプション指定なし)の場合は、呼び元のバッチスクリプトは実行先のバッチスクリプトの終了を待たないので、同時に実行することができます。


2.環境情報

今回のバッチスクリプト実行で使用した環境は以下のバージョンとなっています。

OSWindows11 Home 64ビット
OS ビルドVersion 10.0.26100.3624

3.使用コマンド

今回使うSTARTコマンドのヘルプを見てみます。

以下、STARTコマンドのヘルプ(コマンド「START /?」の実行結果)より

C:\Users\rfrom>start /?
指定されたプログラムまたはコマンドを実行するためにウィンドウを開きます。

START ["タイトル"] [/D パス] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
      [/NODE <NUMA ノード>] [/AFFINITY <16 進数の関係マスク>] [/WAIT] [/B]
 [/MACHINE <x86|amd64|arm|arm64>][コマンド/プログラム] [パラメーター]

    "タイトル"  ウィンドウのタイトル バーに表示するタイトル。
    パス        開始するディレクトリ。
    B           新しいウィンドウを作成せずにアプリケーションを起動します。
                アプリケーションは Ctrl + C を無視します。
                アプリケーションで Ctr l+ C を有効にしていない場合、
                Ctrl + Break がアプリケーションを中断する唯一の方法です。
    I           新しい環境は、現在の環境ではなく、cmd.exe に渡された元の環境に
               なります。
    MIN         ウィンドウを最小化の状態で起動します。
    MAX         ウィンドウを最大表示の状態で起動します。
    SEPARATE    16 ビットの Windows プログラムを別メモリ領域で起動します。
    SHARED      16 ビットの Windows プログラムを共有メモリ領域で起動します。
    LOW         IDLE 優先度クラスでアプリケーションを起動します。
    NORMAL      NORMAL 優先度クラスでアプリケーションを起動します。
    HIGH        HIGH 優先度クラスでアプリケーションを起動します。
    REALTIME    REALTIME 優先度クラスでアプリケーションを起動します。
    ABOVENORMAL ABOVENORMAL 優先度クラスでアプリケーションを起動します。
   BELOWNORMAL BELOWNORMAL 優先度クラスでアプリケーションを起動します。
    NODE        優先 NUMA
                (Non-Uniform Memory Architecture) ノードを 10 進数の整数で指定します。
    AFFINITY    プロセッサの関係マスクを 16 進数で指定します。
                プロセスはこれらのプロセッサで実行されるように制限されます。

                /AFFINITY と /NODE を組み合わせると、関係マスクは異なって
                解釈されます。NUMA ノードのプロセッサ マスクを右にシフトして
                ビット 0 で始まるかのように関係マスクを指定します。
                プロセスは、指定した関係マスクと NUMA ノードの間で共通する
               プロセッサ上で実行されるように制限されます。
                共通するプロセッサがない場合は、プロセスは指定した NUMA ノード上で実行される
                ように制限されます。
    WAIT        アプリケーションを起動し、終了するまで待ちます。
 MACHINE アプリケーション プロセスのマシン アーキテクチャを指定します。

 コマンド/プログラム
                内部コマンドまたはバッチ ファイルの場合、コマンド プロセッサ
                は cmd.exe の /K オプションを使用して実行されます。
                これはコマンドの後でもウィンドウが残ることを意味
                します。

                内部コマンドまたはバッチ ファイルではない場合、そのプログラム
                はウィンドウ モードのアプリケーションまたはコンソール
                アプリケーションとして動作します。

    パラメーター  コマンド/プログラムに渡すパラメーターです。

注意: SEPARATE および SHARED オプションは 64 ビット プラットフォームではサポートされません。

/NODE を指定すると、NUMA システム上のメモリ局所性を利用する方法でプロセスが
作成されるようにできます。たとえば、共有メモリ経由で互いに頻繁に通信する
2 つのプロセスを、メモリ待ち時間を最小限に抑えるために同じ優先 NUMA ノードを
共有するように作成できます。これらのプロセスは可能であれば同じ NUMA ノードから
メモリを割り当て、指定したノード外
のプロセッサ上で実行されることもあります。

    start /NODE 1 application1.exe
    start /NODE 1 application2.exe

これら 2 つのプロセスは、さらに、同じ NUMA ノード内の特定のプロセッサ上で
実行されるように制限できます。次の例では、application1 がノードの低順位の
2 つのプロセッサ上で実行されるのに対し、application2 はノードの次の 2 つの
プロセッサ上で実行されます。この例では、指定したノードに少なくとも 4 つの
論理プロセッサがあることを想定しています。ノード番号は、関係マスクを変更しなくても、
そのコンピューターの任意の有効なノード番号に変更できることに注意してください。

    start /NODE 1 /AFFINITY 0x3 application1.exe
    start /NODE 1 /AFFINITY 0xc application2.exe

コマンド拡張機能を有効にすると、コマンド ラインまたは START コマンドに
よる外部コマンドの起動は、次のように変更されます:

非実行可能ファイルは、ファイル名をコマンドとして入力することによって、
    ファイルの関連付けを使って開くことができます (例:  WORD.DOC は .DOC
    ファイル拡張子に関連付けられているアプリケーションを起動します)。
    コマンド スクリプト内でファイルの関連付けを作成する方法については、
    ASSOC と FTYPE コマンドを参照してください。

32 ビット GUI アプリケーションを実行する場合、CMD.EXE は、
    アプリケーションの終了を待たずにコマンド プロンプトに戻ります。
    コマンド スクリプト内で実行する場合は、
    この動作は発生しません。

最初のトークンが拡張子やパス修飾子を持たない文字列 "CMD" であるコマンド
    ラインを実行する場合、"CMD" が COMSPEC 変数の値で
    置き換えられます。
    これにより現在のディレクトリの CMD.EXE が使われないようにします。

最初のトークンが拡張子を含まないコマンド ラインを実行する場合、CMD.EXE
    は、PATHEXT 環境変数の値を使って拡張子の種類と順序を判断します。
    PATHEXT 変数の既定値は、次のとおりです:

        .COM;.EXE;.BAT;.CMD

    この構文は PATH 変数と同じであり、各要素はセミコロンで区切られて
    いることに注意してください。

実行可能なファイルを検索するときにどの拡張子でも一致するファイルが見つ
からない場合は、拡張子なしの名前がディレクトリ名と一致するかどうかを
調べます。
一致する場合は、START コマンドがそのパスでエクスプローラーを起動
します。コマンド ラインから実行した場合は、そのパスに対する CD /D の実
行と同じになります。

ヘルプからは、今回必要なオプションは無いのでそのままSTARTのパラメータに実行するバッチスクリプトを指定するだけです。

[ コマンド例 ]

START [スクリプトのパス]実行するバッチスクリプト①.bat
START [スクリプトのパス]実行するバッチスクリプト②.bat
START [スクリプトのパス]実行するバッチスクリプト③.bat

4.作成スクリプト

4-1.コード内容

今回作成したスクリプトファイルのコード内容は以下の通りです。

[ ParallelRun.bat ]

@ECHO OFF
@REM ------------------------------------------------------------
@REM 初期処理
@REM ------------------------------------------------------------
@REM 実行バッチファイルディレクトリ設定
SET CMD_PATH=%~dp0

@REM ------------------------------------------------------------
@REM 処理開始メッセージ
@REM ------------------------------------------------------------
ECHO %DATE:~0,4%年%DATE:~5,2%月%DATE:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 処理開始

@REM ------------------------------------------------------------
@REM 別バッチスクリプト並列実行
@REM ------------------------------------------------------------

START %CMD_PATH%TEST001.bat

START %CMD_PATH%TEST002.bat

START %CMD_PATH%TEST003.bat

@REM ------------------------------------------------------------
@REM 正常終了処理
@REM ------------------------------------------------------------
:END
ECHO %DATE:~0,4%年%DATE:~5,2%月%DATE:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 正常終了
ECHO.

EXIT /B



[ TEST001.bat ]

@ECHO OFF
@REM ------------------------------------------------------------
@REM 処理①
@REM ------------------------------------------------------------

ECHO "TEST001.bat 実行中"
TIMEOUT /T 15

@REM ------------------------------------------------------------
@REM 正常終了処理
@REM ------------------------------------------------------------
:END

ECHO.

EXIT 0



[ TEST002.bat ]

@ECHO OFF
@REM ------------------------------------------------------------
@REM 処理②
@REM ------------------------------------------------------------

ECHO "TEST002.bat 実行中"
TIMEOUT /T 15

@REM ------------------------------------------------------------
@REM 正常終了処理
@REM ------------------------------------------------------------
:END

ECHO.

EXIT 0



[ TEST003.bat ]

@ECHO OFF
@REM ------------------------------------------------------------
@REM 処理③
@REM ------------------------------------------------------------

ECHO "TEST003.bat 実行中"
TIMEOUT /T 15

@REM ------------------------------------------------------------
@REM 正常終了処理
@REM ------------------------------------------------------------
:END

ECHO.

EXIT 0

4-2.ディレクトリ構成

作成したバッチスクリプトを実行する際のディレクトリ・ファイル構成です。
今回実行するバッチスクリプトは「ParallelRun.bat」です。
「ParallelRun.bat」の中から「TEST001.bat」「TEST002.bat」「TEST003.bat」が実行されます。

4-3.機能説明

①開始処理
・処理開始メッセージを以下の書式で標準出力に出力する。
「スクリプトID YYYY年MM月DD日 hh時mm分ss秒 処理開始」

②メッセージ表示処理
・バッチスクリプト「TEST001.bat」(メッセージ表示処理)を実行する。

③メッセージ表示処理
・バッチスクリプト「TEST002.bat」(メッセージ表示処理)を実行する。

④メッセージ表示処理
・バッチスクリプト「TEST003.bat」(メッセージ表示処理)を実行する。

⑤終了処理
・終了メッセージを以下の書式で標準出力し処理を終了する。
「スクリプトID YYYY年MM月DD日 hh時mm分ss秒 処理終了」


5.実行結果確認

①バッチスクリプトを実行

②コマンドプロンプトのウィンドウが3つ立ち上がり、それぞれ「TEST001.bat」「TEST002.bat」「TEST003.bat」が実行されていることを確認する。

6.おわりに

逐次実行と並行実行でCALLとSTARTを使い分けましたが、STARTでもWAITオプションを指定することでCALLと同じような使い方もできます。


[コマンド例]

START /WAIT バッチスクリプト.bat

WAITオプションを指定した場合は、実行先バッチスクリプトの処理終了を待ってから次のコードを実行します。

以上です。
宜しくお願い致します。


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