等待多个应用程序从批处理文件异步运行以完成

Jad*_*ded 14 batch-file multiple-instances wait

有一个简单的Windows批处理文件,它运行多个应用程序实例:

start app.exe param1
start app.exe param2
Run Code Online (Sandbox Code Playgroud)

有没有办法同时异步运行它们(上面做的)并等待它们完成执行其他操作 - 类似于C#

Task.WhenAll(tasksList.ToArray());
/* Process tasksList.Result */
Run Code Online (Sandbox Code Playgroud)


/ wait开关在这里没有帮助,如果特定实例仍在运行,可能会进行一些轮询.

dbe*_*ham 21

我想这个问题与等待并行批处理脚本略有不同,因为该应用程序正在等待.exe进程完成而不是批处理脚本.但解决方案几乎相同.

您必须在主批处理脚本中实例化某种形式的轮询.您可以通过重定向有效地创建锁定文件.锁定文件保持锁定状态,直到进程终止.您的批处理脚本轮询,检查它是否可以打开所有锁定文件.一旦成功,它就知道所有过程都已结束.

下面解决方案中唯一的显着区别是START直接启动.exe而不是启动批处理CMD /C.我还了解到,这(call )是一种非常快速的方法,可以有效地执行始终成功的无操作.所以我代替(call )了替代rem

@echo off
setlocal
set "lock=%temp%\wait%random%.lock"

:: Launch processes asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
start "" 9>"%lock%1" notepad.exe
start "" 9>"%lock%2" notepad.exe

:Wait for both processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (1 2) do (
  (call ) 9>"%lock%%%N" || goto :Wait
) 2>nul

::delete the lock files
del "%lock%*"

:: Finish up
echo Done - ready to continue processing
Run Code Online (Sandbox Code Playgroud)

请参阅shell进程的并行执行,以获得锁定技术的非常复杂的应用程序,该技术可以调节并行进程的最大数量,并能够通过进程将进程定向到特定的CPU或计算机PSEXEC.该答案还提供了有关锁定文件技术如何工作的更全面的解释.


编辑

可以修改等待循环,以便在添加更多进程时不需要更改:

:Wait for all processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%F in ("%lock%*") do (
  (call ) 9>"%%F" || goto :Wait
) 2>nul
Run Code Online (Sandbox Code Playgroud)

  • @Crow 1)和3)是的.2)和4)没有.`>`字符是重定向操作符.`1> nul`禁用stdout输出.`2> nul`禁用stderr输出.他们必须保持不变.PING命令是一个黑客,它引入了大约1秒的延迟而不消耗CPU资源.它可以被`> nul timeout 1/nobreak`取代,除了一些旧机器没有那个命令. (3认同)