这就是我想要做的。假设我有一个名为myprogram.exe
的程序,我必须执行1000次。
在Windows下,我通常可以做一些简单的事情:
for /L %n in (1,1,1000) do start /myfolder/myprogram.exe
但是,假设我只有5个CPU线程可以投入运行myprogram.exe
的1000个实例,因此我仅启动5个,那么当其中一个完成时又启动另一个,依此类推,直到整个1000结束。
在Linux上并使用GNU Parallel,我可以简单地做到:
seq 1000 | parallel -N0 -j5 "nohup myprogram.exe"
如何在Windows命令行中实现类似的功能?请注意,在我的情况下,使用 Cygwin并不是一个选择,因此在Windows下使用xargs和GNU Parallel也不是一个选择。
答案 0 :(得分:3)
这将并行运行五个进程。每次完成其中一个操作时,都会开始下一个过程(因此,一共有5个操作,直到全部完成)
@ECHO off
setlocal enabledelayedexpansion
set bunch=5
for /l %%a in (1,1,1000) do (
call :loop
echo processing: %%a
start "MyCommand" cmd /c timeout !random:~-1!
)
call :loop
goto :eof
:loop REM waits for available slot
for /f %%x in ('tasklist /fi "windowtitle eq MyCommand" ^| find /c "cmd.exe"') do set x=%%x
if %x% geq %bunch% goto :loop
goto :eof
将/min
开关添加到start
,以最小化启动的进程。
给他们一个唯一的窗口标题(此处为MyCommand
),以便能够对其进行计数。
将cmd /c timeout !random:~-1!
替换为您的实际命令。
编辑:经过稍微修改的脚本,如果myprogram
是GUI,则可能会更好地工作(上述脚本在CLI应用程序中会更好地工作):
@ECHO off
setlocal enabledelayedexpansion
set bunch=5
for /l %%a in (1,1,100) do (
call :loop
echo processing: %%a
start notepad.exe
)
call :loop
goto :eof
:loop REM waits for available slot
for /f %%x in ('tasklist /fi "imagename eq Notepad.exe"^|find /c "."') do set x=%%x
if %x% geq %bunch% goto :loop
goto :eof
答案 1 :(得分:3)
这是一种使用Powershell进行进程计数的方法。并使用简单的set /a
作为计数器。
@echo off
setlocal enabledelayedexpansion
set /a cnt=0
:counter
if !cnt! lss 1000 (
for /F "tokens=*" %%i in ('powershell ^(Get-Process -Name 'myprogram'^).count') do set proc=%%i
if !proc! lss 5 (
start "C:\myfolder\myprogram.exe"
set /a cnt+=1
)
goto :counter
)
如果要查看计数,可以在echo !cnt!
之前的行中添加goto :counter
。
无需使用delayedexpansion
即可完成操作,但我更喜欢在这里使用。