【问题标题】:Waiting for async batch tasks to finish not properly working等待异步批处理任务完成无法正常工作
【发布时间】:2020-12-21 11:32:46
【问题描述】:

我创建了这个脚本,灵感来自this answer,关于如何等待并行批处理脚本完成并创建了这个。

@echo off

set "lock=%temp%\wait%random%.lock"

start "1" /D .\RESULTS\1 cmd /c  9>"%lock%0" "1.exe"
start "2" /D .\RESULTS\2 cmd /c  9>"%lock%1" "2.exe"
start "3" /D .\RESULTS\3 cmd /c  9>"%lock%2" "3.exe"
start "4" /D .\RESULTS\4 cmd /c  9>"%lock%3" "4.exe"

:Wait0 for all scripts to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (0 1 3) do (
  setlocal enabledelayedexpansion
  set L=!!lock!%%N!
  ( rem
  ) 9>!L! || goto :Wait0
) 2>nul

timeout /t 10 /nobreak
echo 1 done
echo 2 done
echo 3 done
echo 4 done





start "5" /D .\RESULTS\5 cmd /c  9>"%lock%4" "5.exe"
start "6" /D .\RESULTS\6 cmd /c  9>"%lock%5" "6.exe"
start "7" /D .\RESULTS\7 cmd /c  9>"%lock%6" "7.exe"
start "8" /D .\RESULTS\8 cmd /c  9>"%lock%7" "8.exe"

:Wait1 for all scripts to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (4 1 7) do (
  setlocal enabledelayedexpansion
  set L=!!lock!%%N!
  ( rem
  ) 9>!L! || goto :Wait1
) 2>nul

timeout /t 10 /nobreak
echo 5 done
echo 6 done
echo 7 done
echo 8 done




start "9" /D .\RESULTS\9 cmd /c  9>"%lock%8" "9.exe"
start "10" /D .\RESULTS\10 cmd /c  9>"%lock%9" "10.exe"

:Wait2 for all scripts to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (8 1 9) do (
  setlocal enabledelayedexpansion
  set L=!!lock!%%N!
  ( rem
  ) 9>!L! || goto :Wait2
) 2>nul

timeout /t 10 /nobreak
echo 9 done
echo 10 done


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

一开始,1.exe2.exe3.exe4.exe 似乎一切正常,循环正在等待,而所有这些都完成工作,然后才继续。问题从5.exe6.exe7.exe8.exe 的第二个循环开始。然后在 2 或 3 个程序完成后,它的工作循环退出并且不等待最后一个程序完成它的工作。 Any1 可以看到此脚本中的错误,只是这可能不是最有效的编写方式?

【问题讨论】:

    标签: windows batch-file


    【解决方案1】:

    好吧,我试图理解那个锁背后的魔力,发现它是一个 .lock 文件本身做了一个把戏。所以我创建了一些更简单的东西而不是set "lock=%temp%\wait%random%.lock"

    echo. 2>lock0.lock
    echo. 2>lock1.lock
    echo. 2>lock2.lock
    echo. 2>lock3.lock
    

    只有 4 个锁定文件,因为我只打算一次运行 4 个 .exe 文件。然后改了这些行

    start "1" /D .\RESULTS\1 cmd /c  9>"%lock%0" "1.exe"
    start "2" /D .\RESULTS\2 cmd /c  9>"%lock%1" "2.exe"
    start "3" /D .\RESULTS\3 cmd /c  9>"%lock%2" "3.exe"
    start "4" /D .\RESULTS\4 cmd /c  9>"%lock%3" "4.exe"
    

    start "1" /D .\RESULTS\1 cmd /c  9>"lock0.lock" "1.exe"
    start "2" /D .\RESULTS\2 cmd /c  9>"lock1.lock" "2.exe"
    start "3" /D .\RESULTS\3 cmd /c  9>"lock2.lock" "3.exe"
    start "4" /D .\RESULTS\4 cmd /c  9>"lock3.lock" "4.exe"
    

    并将循环内部更改为

    ( rem
    ) 9>"lock0.lock" || goto :Wait0
    ( rem
    ) 9>"lock1.lock" || goto :Wait0
    ( rem
    ) 9>"lock2.lock" || goto :Wait0
    ( rem
    ) 9>"lock3.lock" || goto :Wait0
    

    最后删除所有锁文件

    del "lock0.lock"
    del "lock1.lock"
    del "lock2.lock"
    del "lock3.lock"
    

    我知道这是一个肮脏的解决方案,但也许有人会觉得这很有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多