1

I'm trying to write a batch file that, for a set of numbers (1 to 10), starts an executable sequentially. The numbers from the set of numbers are being passed to a file for the executable to run in batch mode. However, because the executable hogs resources, I want only 5 of these executables running at a time (there will be a total of 1500 executable runs in total). I've jimmy-rigged some script to monitor the tasklist and to not continue starting the executable while 5 of the executable are currently running. Once the number of tasks goes back down to 4, the next executable will be started.

Simplified minimum working example (I'm obviously not running notepad):

FOR %%g IN (1 2 3 4 5 6 7 8 9) DO (
    :loop
    tasklist | find /I /C "OpenSees.exe" >process.txt
    FOR /F "tokens=*" %%a IN (process.txt) DO (
        IF "%%a" EQU "5" (goto :loop)
    )           
    start notepad.exe
    PAUSE
)

What happens here is that once %%a does equal 5, goto is invoked, and the loop works fine and doesn't start more executables. However, once one "notepad" is closed, the waiting loop is broken (as intended), but the initial FOR loop is also broken (%%g is no longer a defined variable) and the script ends without %%g passing 5 to 6 7 8 and 9. Echo %%g gives back echo %g while the waiting loop is looping through.

What am I doing wrong here?

Thank you in advance.

1 Answers1

0

I think this fixes your problem:

@setlocal ENABLEEXTENSIONS
@set prompt=$G

@rem Change this to whatever program you want to run.
@set _programToRun=notepad.exe

@for %%g in (1 2 3 4 5 6 7 8 9) do @call :TaskMonitor %%g

@exit /b 0

:TaskMonitor
@tasklist | find /I /C "%_programToRun%" > process.txt
@set /p "_procCount=" < process.txt
@echo %%1==%1 _procCount==%_procCount%
@rem Uncomment the next line, remove this line and the one following the next.
@rem @if _procCount lss 5 (start %_programToRun% %1 & exit /b 0)
@if %_procCount% lss 5 (start %_programToRun% & exit /b 0)
@goto :TaskMonitor

Always avoid multi-line for loop bodies (or if/else blocks for that matter), they are just not worth the effort required to debug them. Call out to a subroutine is the best way avoid those issues.

jwdonahue
  • 6,199
  • 2
  • 21
  • 43