我面临一个非常愚蠢的问题。我有一个由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
答案 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
命令无法避免这种行为!你能否就这一点向我们提供更多细节?