START / WAIT和/ B的组合可能吗?

时间:2015-03-19 10:59:30

标签: batch-file cmd

我面临一个非常愚蠢的问题。我有一个由NAnt脚本生成的命令列表。这些存储在bat文件中。在每一行我都用几个参数调用一个exe。 exe对一组文件进行操作并修改它们。文件集始终相同。我们正在讨论大约1000个exe的调用,所以如果每次出现一个新的控制台,我都会遇到性能问题。 “没问题”我想到并将START /B添加到每个命令行,所以现在exe在后台启动,工作速度更快。 现在问题出在这里:正如我所提到的,exe对同一组文件进行操作,因此有时会发生无法修改文件的问题,因为它已经被程序的不同实例打开而导致崩溃。我想在每个调用中添加/W参数,以确保永远不会同时运行两个实例。但是这会以某种方式禁用/B参数。

所以我的问题是:是否有可能让我的exe在后台启动并强制我的批处理等待每个实例终止?

请不要告诉我这很难看。我知道,但我无法改变设置。我的公司多年来一直在使用这个s ***,我唯一可以修改的是生成的bat文件。

以下是生成的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

3 个答案:

答案 0 :(得分:4)

您可以在没有start /b的情况下使用/wait并构建自己的同步。

等待文件lock.tmp不再被start命令锁定。

此示例使用calc.exe进行演示 使用ping命令等待一秒是很有用的,因为没有ping,cpu使用率将达到100% 但我的测试表明,等待时cpu只有5%。

@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

编辑:直接等待的解决方案

这使用管道将阻塞直到生产者完成的事实 该解决方案在等待循环中不需要额外的CPU性能,并且可以在作业完成后立即启动下一个作业。

@echo off

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

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

答案 1 :(得分:1)

您可以将文件用作标志来检测.exe文件是否正在运行。在每次执行.exe之前创建标志文件,并在.exe结束时将其删除。这样,批处理文件只需要等待标志文件消失,然后再启动下一个.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

为了获得更好的性能,您可以在ping子例程中调整:waitForProcess等待时间,使其等待.exe结束的时间大致相同。如果.exe只需要几毫秒,您可以完全省略ping命令。

答案 2 :(得分:0)

对不起,我觉得这里有一个混乱。

START命令用于与同一程序的其他实例并行运行给定程序的多个实例(异步方式)。当{Wait(1)}命令与/ Wait开关一起使用时,最终结果与完全省略START命令的结果相同。放置在批处理文件中的命令以顺序方式执行:下一个命令开始,直到前一个结束。如果在没有START的情况下执行相同的命令,则会得到相同的结果。

如果您省略生成的批处理文件中存储的命令中的START /W部分,我认为您将解决您的问题。执行.exe文件不应该打开一个新的cmd.exe窗口,但如果它这样做,那么start /B /W命令无法避免这种行为!你能否就这一点向我们提供更多细节?