【问题标题】:Limit number of batch files launched by FOR loop限制 FOR 循环启动的批处理文件数
【发布时间】:2026-01-25 15:20:03
【问题描述】:

我有一个批处理文件,可以下载 21 个单独的文件(都非常大)。在尝试获取更多文件之前,我有超时尝试让一些文件完成(不是一个好的解决方案),如果它们一起运行,它会占用我所有的系统资源,一切都会停止。

我可以将 /WAIT 放在我的 FOR 循环中,然后它一次只会启动一个下载任务。我想启动 5 个下载窗口,完成后,继续下一个 5。我尝试使用 GOTO 等到完成,但它不起作用。

rem *****Step 1*****
set tstart=0
set tend=5
set incr=1
FOR /L %%a IN (%tstart%,%incr%,%tend%) DO (start /ABOVENORMAL GET_PIECE_ENSEMBLE.bat %newformatdate% 0%%a %HH%)
timeout /t 30

:WAIT
if exist flagfile.* goto WAIT

然后我还有 4 个步骤来下载文件 5-10、11-16 等。但如果下载时间过长,脚本会继续执行并开始下载更多文件或继续执行下一个进程,这需要首先要下载的所有数据。我在这里尝试两件事:确保数据已开始下载的短暂超时(因此存在标志文件),如果存在标志文件则等待。但是等待不起作用,脚本仍在继续并开始下载下一组。我的解决方法是将超时设置为 600,但有时下载数据需要超过 10 分钟,有时会挂起并需要长达两个小时,有时只需几分钟。如果所有部分同时启动,它会冻结工作站,我们必须重新启动机器。

这里是 GET_PIECE_ENSEMBLE 的代码,在 FOR 循环中运行的脚本:

set "newformatdate=%1"
set "ename=%2"
set "HH=%3"
echo %time% > flagfile.%ename%
wget -O C:/Data/DataFile_%HH%.%ename%.grb2 http://url/%newformatdate%.grib2
del flagfile.%ename%

寻找有关如何使“如果标志文件存在则等待”工作的建议(知道为什么这不起作用吗?),或者是否有一些简单的参数可以放入我的 FOR 循环中以限制实例所以下载在其他人开始之前完成?当网络条件变化很大时,肯定有比猜测超时间隔更好的解决方案!

【问题讨论】:

  • 因此,不是在任何给定时间运行不超过五次,而是希望等到五次完整的一组完成后再继续下一组五次?
  • 无论哪种方式,我只想启动多个(以利用带宽)但不是全部 21 个,因为它太多了,它们都运行得很慢,并且导致工作站崩溃。

标签: windows batch-file cmd wget


【解决方案1】:

在 GET_PIECE_ENSEMBLE 中

试试

...
set "HH=%3"
:only5
set /a running=0
for /f %%c in ('dir /b/a-d flagfile.* 2^>nul') do set /a running+=1
if %running% geq 5 (
 timeout /t 1 >nul
 goto only5
)
echo %time% > flagfile.%ename%
...

应该计算标志文件,当有 5 个或更多时,延迟 1 秒。

一旦一个标志文件被删除,下一个被激活的排队文件将再次将进程中文件的数量增加到 5 个,从而阻塞其他排队的进程。

【讨论】:

  • 所有 21 个窗口同时启动,因为直到下载连接建立后才会创建标志文件,这需要几秒钟。
  • 我同意所有 21 个都已启动,但是应该在执行 wget 之前创建标志文件,因此只有 5 个 wgets 应该并行执行。我不明白为什么在建立下载连接之后才生成标志文件。它应该在执行wget 之前生成。请进一步解释。
【解决方案2】:

未经测试!!!

:: Start with list of files to download as parameters
:: down.cmd "file1" "file2" "file3" etc.. 
@echo off
set "url=http://host.com"
:loop
for /f %%a in ('tasklist /FI "imagename eq wget.exe" /FI "windowtitle eq _download*" /FO csv /NH ^| find /C "wget"') do (
if %%a LEQ 5 (
            start "_download" "%path%\wget.exe" -O "%~1" "%url%/%~1"
            shift
            )
timeout /T 5
if not "%~1"=="" goto loop

【讨论】:

    最近更新 更多