使用批处理脚本在 Windows 上运行所需数量的可执行文件

使用批处理脚本在 Windows 上运行所需数量的可执行文件

我有几个目录(> 20),其中包含一个 Windows 可执行文件(.EXE),该文件接受一些输入文件并生成输出(output.txt),所有这些都位于同一目录中。在我的 Windows 10 PC(x64)上有 8 个 CPU,我可以使用以下(小巧可爱的)批处理脚本同时运行所有 EXE(作业)run_jobs.bat

@echo off
FOR /d /r %%i IN (*) DO (
   if exist "%%i\run_jobs.bat" start "" /d "%%i" "%comspec%" /c "run_jobs.bat"
)

问题是,所有 PC 资源都被消耗了(使用率 100%),没有空间用于其他进程。有没有办法控制/调度上述循环,使其同时只运行 7 个作业(= 7 个 CPU),为其他进程保留一些资源,直到所有目录中的所有排队执行都完成?我愿意接受批处理或 PowerShell 脚本建议。

答案1

@echo off & setlocal

for /d /r %%i in (*)do if exist "%%~i\run_jobs.bat" call %:^) "%%~dpnxi" "run_jobs.bat"

endlocal && goto :eof

%:^)
if not "%~1" == "" (set "_path=%~1" && set "_bat=%~2")
for /f %%i in ('wmic process where "name like '%%cmd.exe%%'" get commandline ^| findstr /c:"%_bat%" ^| find /v /c ""
    ')do if %%~i leq 6 (start "" /b /d "%_path%" %comspec% /s /c "%_path%\%_bat%") else >nul (timeout 10 & goto %:^)) 

1.发送到函数/标签%:ˆ)到bat文件的路径找到它的名称。

call %:^) "%%~dpnxi" "run_jobs.bat"

2.当调用该函数时(与 goto 不同),它会获取参数(%~1%~2),并将它们保存在变量中以供for /f循环使用......

if not "%~1" == "" (set "_path=%~1" && set "_bat=%~2")
    ... for /f ... (... "%_bat%") do ...
 if ... (start ... "%_path%" ...  "%_path%\%_bat%"
    ) else (... goto %:^)  

3.循环内的命令for /f ...(wmic|findstr|find)将使用重定向器来获取启动与参数中传入的同名蝙蝠的命令的路径,并且它还将计算正在运行的蝙蝠数量......

for /f %%i in ('wmic process where "name like '%%cmd.exe%%'" get commandline ^| findstr /c:"Your_Bat_File_Name" ^| find /v /c ""
  • 观察:1 Wmic使用过滤器|findstr |Find /Count将返回数字0-7

  • 观察:2对于 Windows 11 用户,我建议检查Wmic是否安装....


4.条件if ()else测试循环输出,如果循环中的输出小于或等于6,则调用当前%_bat%执行,否则等待timeout 10 seconds,并再次检查计数/再次循环输出goto %:^)

if %%~i leq 6 (start "" /b /d "%_path%" %comspec% /s /c "%_path%\%_bat%") else >nul (timeout 10 & goto %:^))

5.当它在循环中返回时goto %:ˆ),它会检查这次是否传递了任何参数,如果没有,则忽略并继续使用已经定义的变量,并且如果一个或多个蝙蝠已经完成,则这个新调用的输出将会更小并且会使函数中使用的蝙蝠被执行,或者开始新的等待......

if not "%~1" == "" (...) // if this time is processing redirection by goto ignore //

for /f (wmic...) do if %%~i leq 6 (
     start "%_path%\%_bat%"
   ) else ( 
     timeout 10
     goto %:^)
   )

6.for /r /d循环结束时,endlocal 也结束并到达文件末尾......

for /d /r ... (*)do .... // end

endlocal && goto :eof

其他资源:

相关内容