マルチスレッドWindows FORバッチコマンド


11

複数のスレッドのバッチファイルでFORコマンドを実行する簡単な方法があるかどうか知っていますか?4つの並列スレッドでタスクを実行できない場合、4つのコアがあることの意味は何ですか?

たとえば、PNGOUTでPNGを最適化している場合、使用するコマンドは

for %i in (*.png) do pngout "%i"

しかし、これは非常に並列化可能なタスクであり、サブタスクは相互にまったく依存しません。

これを4つの「キュー」で実行するには、次のようにします。

for -thread 4 %i in (*.png) do pngout "%i"

これを実行できる独自のfor-likeアプリを作成する必要がありますか、それとも利用可能な無料のソリューションはありますか?


外部ツールの使用に関する回答を確認してください:[ stackoverflow.com/a/12041213/365229] [1] [1]:stackoverflow.com/a/12041213/365229
Behrouz.M

回答:


13

先ほどのスタックオーバーフローで最大数のコマンドのみを実行するバッチファイルを作成しました。シェルプロセスの並列実行

@echo off
for /l %%i in (1,1,20) do call :loop %%i
goto :eof

:loop
call :checkinstances
if %INSTANCES% LSS 5 (
    rem just a dummy program that waits instead of doing useful stuff
    rem but suffices for now
    echo Starting processing instance for %1
    start /min wait.exe 5 sec
    goto :eof
)
rem wait a second, can be adjusted with -w (-n 2 because the first ping returns immediately;
rem otherwise just use an address that's unused and -n 1)
echo Waiting for instances to close ...
ping -n 2 ::1 >nul 2>&1
rem jump back to see whether we can spawn a new process now
goto loop
goto :eof

:checkinstances
rem this could probably be done better. But INSTANCES should contain the number of running instances afterwards.
for /f "usebackq" %%t in (`tasklist /fo csv /fi "imagename eq wait.exe"^|find /v /c ""`) do set INSTANCES=%%t
goto :eof

並行して実行され、最小化される最大4つの新しいプロセスを生成します。待機時間は、各プロセスの実行時間と実行時間に応じて、おそらく調整する必要があります。おそらく、何か他のことをしている場合は、タスクリストが探しているプロセス名を調整する必要もあります。

ただし、このバッチによって生成されたプロセスを適切にカウントする方法はありません。1つの方法は、バッチの開始時に乱数を作成し(%RANDOM%)、処理を実行する(または処理プログラムを生成する)ヘルパーバッチを作成しますが、ウィンドウのタイトルをパラメーターに設定できます。

@echo off
title %1
"%2" "%3"

これは、最初のパラメーターにタイトルを設定し、3番目のパラメーターを引数として2番目のパラメーターを実行する単純なバッチです。次に、指定されたウィンドウタイトル(tasklist /fi "windowtitle eq ...")のプロセスのみを選択することにより、タスクリストでフィルタリングできます。これはかなり信頼性の高い方法で動作し、誤検出が多すぎないようにします。cmd.exeまだいくつかのインスタンスが実行されている場合、ワーカープロセスのプールが制限されるため、検索は悪い考えです。

を使用%NUMBER_OF_PROCESSORS%して、スポーンするインスタンス数の適切なデフォルトを作成できます。

これを簡単に適合させてpsexec、リモートでプロセスを生成することもできます(ただし、他のマシンの管理者権限と、バッチでパスワードを提供する必要があるため、あまり実用的ではありません)。ただし、その場合はフィルタリングにプロセス名を使用する必要があります。


これは深刻なブラックバッチマジックです!もっと投票できるといいのに!
Axarydax 2011年

Joey

コマンド 'wc'は、Win10コマンドラインでは使用できません。他に何が使えますか?
PeterCo

1
@PeterCo: find /c /v ""
ジョーイ

1

バッチファイルは非常に基本的なスクリプト用であり、いかなる種類のマルチスレッドもサポートしていません。達成したいことを実行するには、独自のユーティリティを作成する必要があります。

または、Windows PowerShellは、目標に近づくためのより多くの機能を提供する場合があります。

単に複数の操作を同時に実行したい場合は、コマンドstartを使用して、PNGOUTユーティリティを新しいウィンドウで起動できます。FORループは、各操作の終了を待たずに続行します。

変更された行は次のようになります。

for %i in (*.png) do start pngout "%i"

ただし、これにより、ディレクトリ内のすべてのファイルに対して同時にPNGOUTが効果的に起動されることに注意してください。これは、おそらく望ましくありません。


これは素朴なアプローチであり、あなたが言及したように、おそらく望ましくないでしょう。コアの数だけプロセスを起動する必要があります。4つのコアと1,000個のファイルがある場合、1,000個すべてが処理されるまで、一度に4つだけを処理する必要があります。1,000個すべてを4コアで一度に処理しようとすると、コンピューターの速度が低下して無駄なクロールが発生します。
Adisak 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.