MichaelS
MichaelS

Reputation: 6042

Combination of START /WAIT and /B possible?

I'm facing a quite stupid problem. I have a list of commands generated by a NAnt script. These are stored in a bat file. In each line I'm calling an exe with several parameters. The exe operates on a set of files and modifies them. The set of files is always the same. We are talking about ~1000 calls of the exe so if each time a new console would pop up I'd get performance issues. "No problem" I thought and added START /B to each command line so now the exe is started in background which works way faster. Now here's the problem: As I've mentioned, the exe operates on the same set of files so sometimes it happens that a file can't be modified because it's already opened by a different instance of the program which results in a crash. I'd like to add the /W parameter to each call to ensure that never two instances run at the same time. But this somehow disables the /B parameter.

So my question is: is it possible to have my exe started in background AND force my batch to wait for each instance to terminate?

Please don't tell me that this is ugly. I know but I can't change anything about the setup. My company has been working with this s*** for years and the only point where I can make modifications is the generated bat file.

Here is the code of the generated bat:

start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7
start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7
start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7
...
start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7
start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7
start /B /W S:\ome\path\to\my\exe.exe --param1 --param2 "XYZ" --param3 "ZYX" --param4 "1 2 3" --param5 "321" --param6 "1337" --param7

Upvotes: 3

Views: 14766

Answers (3)

jeb
jeb

Reputation: 82267

You can use start /b without /wait and build your own synchronizing.

This waits until the file lock.tmp is no longer locked by the start command.

This example uses calc.exe for demonstration.
It can be useful to use the ping command to wait a second, as without ping the cpu usage will go up to 100%.
But my test says that the cpu is only at 5% while waiting.

@echo off

call :syncExecute
call :syncExecute
call :syncExecute
exit /b

:::::::::::::
:syncExecute
( start /b c:\Windows\System32\calc.exe ) > lock.tmp
:waitForExit
(
  REM ping -n 2 localhost > nul
  echo dummy > lock.tmp
) 2> nul || goto :waitForExit
exit /b

EDIT: Solution with direct waiting

This uses the fact that a pipe will block until the producer is finished.
This solution doesn't needs extra cpu performance in a waiting loop and it can start the next job immediately after a job is finished.

@echo off

call :syncExecute
call :syncExecute
call :syncExecute
exit /b

:::::::::::::
:syncExecute
( start /b c:\Windows\System32\calc.exe ) | more > nul
exit /b

Upvotes: 6

Aacini
Aacini

Reputation: 67216

You may use a file as a flag to detect that the .exe file is running. Create the flag file before each execution of the .exe and remove it when the .exe ends. This way, the Batch file just needs to wait for the flag file to disappear before start the next .exe:

echo X > flag.txt
start "" /B "S:\ome\path\to\my\exe.exe --param1  ...  --param7  &  del flag.txt"
call :waitForProcess
echo X > flag.txt
start "" /B "S:\ome\path\to\my\exe.exe --param1  ...  --param7  &  del flag.txt"
call :waitForProcess
...
echo X > flag.txt
start "" /B "S:\ome\path\to\my\exe.exe --param1  ...  --param7  &  del flag.txt"
call :waitForProcess
echo X > flag.txt
start "" /B "S:\ome\path\to\my\exe.exe --param1  ...  --param7  &  del flag.txt"
call :waitForProcess

goto :EOF

:waitForProcess
ping -n 2 localhost > NUL
if exist flag.txt goto waitForProcess
exit /B

For better performance, you may adjust the ping waiting time in :waitForProcess subroutine so it waits approximately the same time that the .exe takes to end. If the .exe takes just milliseconds, you may entirely omit the ping command.

Upvotes: 1

Aacini
Aacini

Reputation: 67216

Excuse me, I think there is a confusion here.

START command is used to run more than one instance of a given program in parallel (asynchronous way) with other instances of the same program. When START command is used with the /Wait switch, then the final result is the same as if the START command is entirely omitted. The commands placed in a Batch file are executed in sequential way: the next one starts until the previous one ends. This is the same result you get if you execute the same commands without START /W.

I think you will solve your problem if you omit the start /B /W part in the commands stored in the generated Batch file. The execution of the .exe file should not open a new cmd.exe window, but if it does that, then the start command have not a way to avoid that behaviour! Could you give us more details about this point?

Upvotes: 0

Related Questions