【问题标题】:Waiting for Parallel batch scripts or command lines等待并行批处理脚本或命令行
【发布时间】:2017-11-22 21:46:05
【问题描述】:

我发现很难在此处修改脚本以满足我的要求: https://stackoverflow.com/a/12665498/4683898

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

:: Launch one and two asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
start "" cmd /c 9>"%lock%1" one.bat
start "" cmd /c 9>"%lock%2" two.bat

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

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

:: Launch three and four asynchronously
start "" cmd /c three.bat
start "" cmd /c four.bat

我使用的是批处理脚本,不是为了执行进一步的批处理脚本,而是简单地并行执行 cmd 命令(运行一段时间),并且与上面的脚本配合得很好。

但是,我希望能够同时运行 2 个以上的命令/脚本,即 3、4、5(或任何我想要的)命令,并行运行,我们称之为 x。

所以,我想运行 x 个 cmd 命令(在 并行 中执行),等待它们终止(使用 /c),然后执行 next 一堆 x 数量的 cmd 命令,然后是 next 一堆,等等,直到所有的 cmd 命令都执行完毕。

如何相应地修改该脚本? (我已经做了一些尝试,尽管在启动批处理脚本中重复出现错误“该进程无法访问该文件,因为它正在被另一个进程使用。”我认为这个“文件”是指锁定文件。)

谢谢

编辑:

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

call :a start cmd.exe /c somecommandA 1
call :a start cmd.exe /c somecommandB 2
call :wait
call :a start cmd.exe /c somecommandC 1
call :a start cmd.exe /c somecommandD 2
call :a start cmd.exe /c somecommandE 3

exit /b
:a
start "%~2" cmd /c 9>"%lock%%2" %1
exit /b
:wait
1>nul 2>nul ping /n 2 ::1
for %%N in (%lock%*) do (
  ( rem
  ) 9>"%%N" || goto :Wait
) 2>nul

【问题讨论】:

    标签: batch-file cmd parallel-processing


    【解决方案1】:

    您可以使用此脚本轻松调用文件:

    @echo off
    setlocal
    set "lock=%temp%\wait%random%.lock"
    
    
    call :a one.bat 1
    call :a two.bat 2
    call :wait
    call :a three.bat 1
    call :a name.bat 2
    call :a gfwagwa.bat 3
    
    
    exit /b
    :a
    start "%~2" cmd /c 9>"%lock%%2" %1
    exit /b
    :wait
    1>nul 2>nul ping /n 2 ::1
    for %%N in (%lock%*) do (
      ( rem
      ) 9>"%%N" || goto :Wait
    ) 2>nul
    

    call :wait 只是替换了等待。每当您调用了所有要异步运行的文件时,请调用等待函数。然后就可以调用更多的脚本了。

    第二个参数是锁文件的编号。确保在关闭所有使用它们的脚本之前没有重复的数字(即在下一个 call :wait 之前)。尽管无论如何您都不会用完数字,但没有理由使用重复。

    【讨论】:

    • 谢谢。我收到相同的错误“该进程无法访问该文件,因为它正被另一个进程使用。”在启动批处理脚本中。此外,不幸的是它不起作用 - 它只是打开命令提示符等待进一步的命令。请参阅我在上面原始帖子中的编辑,了解我目前拥有的内容。还有其他想法吗?
    【解决方案2】:

    只是为了提供一种替代方式:

    @ECHO off
    start "MyCommand-%~n0" cmd.exe /c ping localhost
    start "MyCommand-%~n0" cmd.exe /c ipconfig /all
    start "MyCommand-%~n0" cmd.exe /c sysinfo
    :loop
    tasklist /fi "windowtitle eq MyCommand-%~n0"  | find "===" >nul && goto :loop
    echo finished!
    

    编辑供您发表评论。 bunch 是并行运行的命令数。

    @ECHO off
    setlocal enabledelayedexpansion
    set bunch=3
    
    for /f "delims=:" %%a in ('findstr /n /b "REM ==" %~f0') do set /a datastart=%%a+1
    set count=0
    for /f "skip=%datastart% usebackq delims=" %%a in ("%~f0") do (
      set /a "count=(count+1) %% %bunch%"
      echo starting: %%a
      start "MyCommand-%~n0" cmd.exe /c %%a
      if !count!==0 echo waiting & call :loop
    )
    echo waiting & call :loop
    echo finished!
    goto :eof
    
    :loop
    tasklist /fi "windowtitle eq MyCommand-%~n0"  | find "===" >nul && goto :loop
    goto :eof
    
    REM == START DATA ==
    ping localhost
    ipconfig /all
    systeminfo
    tasklist
    echo hello
    schtasks /query
    wmic bios get /value
    timeout 10
    

    第一个 for 只是获取您的命令所在的行号(DATA 部分的开头)

    【讨论】:

    • 谢谢斯蒂芬。使用该代码,请问我可以将 10000 多个命令的其余部分放在哪里? (每个命令都不同,我只想能够并行处理一批(即 2、3 或 4 个)。
    • 只是将命令堆叠在批处理文件本身的末尾。当然,您也可以使用外部文件。
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2012-09-19
    相关资源
    最近更新 更多