1

我有一个带有 8GB RAM 的 8 核 CPU,我正在创建一个批处理文件来自动化 7-zip CLI,以耗尽大多数参数和变量来压缩同一组文件,最终目标是找到最强的参数组合和导致最小存档大小的变量。

这本质上非常耗时,尤其是当要处理的文件集以千兆字节为单位时。我需要一种方法,不仅要自动化,还要加快整个过程。

7-zip 使用不同的压缩算法,有些是单线程的,有些是多线程的,有些不需要太多内存,有些需要大量内存,甚至可以超过 8GB 的​​障碍。我已经成功创建了一个按顺序工作的自动批处理,其中排除了需要超过 8GB 内存的组合。

我已经将不同的压缩算法分成几批来简化整个过程。例如,在 PPMd 中压缩为 7z 归档文件使用 1 线程和高达 1024MB。这是我目前的批次:

@echo off
echo mem=1m 2m 3m 4m 6m 8m 12m 16m 24m 32m 48m 64m 96m 128m 192m 256m 384m 512m 768m 1024m
echo o=2 3 4 5 6 7 8 10 12 14 16 20 24 28 32
echo s=off 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1g 2g 4g 8g 16g 32g 64g on
echo x=1 3 5 7 9

for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s
exit

x, s,omem是参数,每个参数后面是 7z.exe 将使用的变量。x在这种情况下,s它们无关紧要,它们意味着存档的压缩强度和实体块大小。

该批次可以正常工作,但仅限于一次仅运行 1 个 7z.exe 实例,现在我正在寻找一种方法使其并行运行更多 7z.exe 实例,但不超过 8GB 的​​ RAM 或 8 个线程一次,以先到者为准,然后再继续执行顺序中的下一个。

我该如何改进呢?我有一些想法,但我不知道如何让它们批量工作。我在考虑其他 2 个变量,它们不会与 7z 进程交互,但会控制下一个 7z 实例何时启动。一个变量将跟踪当前正在使用的线程数,而另一个变量将跟踪正在使用的内存量。那能行吗?

编辑:对不起,我需要添加细节,我是这种发布风格的新手。按照这个答案 - https://stackoverflow.com/a/19481253/2896127 - 我提到创建了 8 个批次,而 7z.PPMd 批次就是其中之一。也许列出所有批次以及 7z 如何处理参数将更好地了解整个问题。我将从简单的开始:

  • 7z.PPMd - 1 个充分利用的线程和字典,每个实例的内存使用量为 32m-1055m。
  • 7z.BZip2 - 8 个充分利用的线程和每个实例固定 109m 的内存使用量。
  • zip.Bzip2 - 8 个部分使用的线程和每个实例固定的 336m 内存使用量。
  • zip.Deflate - 8 个部分使用的线程和每个实例固定的 260m 内存使用量。
  • zip.PPMd - 8 个部分使用的线程和依赖于字典的每个实例的 280m-2320m 内存使用量。

我对部分使用线程的意思是,虽然我为每个 7.exe 实例分配了 8 个线程,但该算法可以以随机方式执行可变 CPU 使用率,这是我无法控制的,不可预测的,但限制设置在那里- 不超过 8 个线程。在 8 个充分利用的线程的情况下,这意味着在我的 8 核 CPU 上,每个实例都在使用 100% 的 CPU。

最复杂的——7z.LZMA、7z.LZMA2、zip.LZMA——需要详细解释,但我现在时间不多了。每当我有更多空闲时间时,我都会回来编辑 LZMA 部分。

再次感谢。


编辑:添加 LZMA 部分。

  • 7z.LZMA - 每个实例都是 n 线程的,范围从 1 到 2:

    • 1 个充分利用的线程,依赖于字典,64k 到 512m:
      • 64k 字典使用 32m 内存
      • ...
      • 512m 字典使用 5407m 内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
    • 2 个部分使用的线程,依赖于字典,64k 到 512m:
      • 64k 字典使用 38m 内存
      • ...
      • 512m字典使用5413m内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
  • 7z.LZMA2 - 每个实例都是 n 线程的,范围从 1 到 8:

    • 1 个充分利用的线程,依赖于字典,64k 到 512m:
      • 64k 字典使用 32m 内存
      • ...
      • 512m 字典使用 5407m 内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
    • 2 或 3 个部分使用的线程,取决于字典,64k 到 512m:
      • 64k 字典使用 38m 内存
      • ...
      • 512m字典使用5413m内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
    • 4 或 5 个部分使用的线程,取决于字典,64k 到 256m:
      • 64k 字典使用 51m 内存
      • ...
      • 256m 字典使用 5677m 内存
      • 排除范围:384m 到 1024m(超过 8192m 可用内存的限制)
    • 6 或 7 个部分使用的线程,取决于字典,64k 到 192m:
      • 64k 字典使用 62m 内存
      • ...
      • 192m字典使用6965m内存
      • 排除范围:256m到1024m(超过8192m可用内存的限制)
    • 8 个部分使用的线程,依赖于字典,64k 到 128m:
      • 64k 字典使用 72m 内存
      • ...
      • 128m字典使用6717m内存
    • 排除范围:192m 到 1024m(超过 8192m 可用内存的限制)
  • zip.LZMA - 每个实例都是 n 线程的,范围从 1 到 8:

    • 1 个充分利用的线程,依赖于字典,64k 到 512m:
      • 64k 字典使用 3m 内存
      • ...
      • 512m字典使用5378m内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
    • 2 或 3 个部分使用的线程,取决于字典,64k 到 512m:
      • 64k 字典使用 9m 内存
      • ...
      • 512m 字典使用 5384m 内存
      • 排除范围:768m 到 1024m(超过 8192m 可用内存的限制)
    • 4 或 5 个部分使用的线程,取决于字典,64k 到 256m:
      • 64k 字典使用 82m 内存
      • ...
      • 256m字典使用5456m内存
      • 排除范围:384m 到 1024m(超过 8192m 可用内存的限制)
    • 6 或 7 个部分使用的线程,取决于字典,64k 到 256m:
      • 64k 字典使用 123m 内存
      • ...
      • 256m 字典使用 8184m (虽然非常接近极限,我可以考虑排除它)
      • 排除范围:384m 到 1024m(超过 8192m 可用内存的限制)
    • 8 个部分使用的线程,依赖于字典,64k 到 128m:
      • 64k 字典使用 164m 内存
      • ...
      • 128m字典使用5536m内存
      • 排除范围:192m 到 1024m(超过 8192m 可用内存的限制)

我试图了解其中带有 nul 的命令的行为。我不太明白那部分发生了什么,那些符号 ^ > ^&1 "" 的意思是什么。

    2>nul del %lock%!nextProc!
    %= Redirect the lock handle to the lock file. The CMD process will     =%
    %= maintain an exclusive lock on the lock file until the process ends. =%
    start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd!
  )
  set "launch="

然后稍后,在 :wait 代码处:

    ) 9>>"%lock%%%N"
  ) 2>nul
  if %endCount% lss %startCount% (
    1>nul 2>nul ping /n 2 ::1
    goto :wait
  )

2>nul del %lock%*

编辑 2(29-10-2013):添加当前情况。

经过反复试验研究,并辅以对正在发生的事情的逐步说明,我能够理解上述行为。我将带有 start 命令的行简化为:

start /b /low cmd /c !cmd!>"%lock%!nextProc!"

虽然有效,但我仍然不明白1^>"filename" 2^>^&1 'command'. 我知道这与在文件名中写入文本有关,否则会显示给我。在这种情况下,它将显示所有 7z.exe 文本但写入文件中。直到 7z.exe 实例完成其工作,文件中没有写入任何内容,但文件已经存在,但同时不存在。当 7z.exe 实际完成时,该文件已完成,这一次它存在于脚本的下一部分。

现在我可以理解建议脚本的处理行为,并用我自己的东西对其进行补充——我正在尝试将所有批次实现为“一个批次完成所有”脚本。在简化版中,是这样的:

echo 8 threads - maxproc=1
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (900k) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=BZip2:d=%%d:mt=%%t
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (900k) DO 7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.zip .\teste.original\* -mx=%%x -mm=BZip2:d=%%d -mmt=%%t
for %%x IN (9) DO for %%t IN (8) DO for %%w IN (257 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.deflate64.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate64:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%t IN (8) DO for %%w IN (258 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.deflate.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (256m 128m 64m 32m 16m 8m 4m 2m 1m) DO for %%w IN (16 15 14 13 12 11 10 9 8 7 6 5 4 3 2) DO 7z.exe a teste.resultado\%%xx.ppmd.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=PPMd:mem=%%d:o=%%w -mmt=%%t

echo 4 threads - maxproc=2
for %%x IN (9) DO for %%t IN (4) DO for %%d IN (256m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t

echo 2 threads - maxproc=4
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t

echo 1 threads - maxproc=8
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t
for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t

简而言之,我想以最有效的方式处理所有这些。通过决定一次可以运行多少个进程来做到这一点是一种方法,但是每个进程也需要内存,因此这些进程所需的所有内存总和不会超过 8192 MB。我让这部分工作。

@echo off
setlocal enableDelayedExpansion

set "maxMem=8192"
set "maxThreads=8"

:cycle1
set "cycleCount=4"
set "cycleThreads=1"
set "maxProc="
set /a "maxProc=maxThreads/cycleThreads"
set "cycleFor1=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO ("
set "cycleFor2=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO ("
set "cycleFor3=for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO ("
set "cycleFor4=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO ("
set "cycleCmd1=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t"
set "cycleCmd2=7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t"
set "cycleCmd3=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s"
set "cycleCmd4=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t"
set "tempMem1=5407"
set "tempMem2=5407"
set "tempMem3=1055"
set "tempMem4=5378"
rem set "tempMem1=5407"
rem set "tempMem2=5407"
rem set "tempMem3=1055 799 543 415 287 223 159 127 95 79 63 55 47 43 39 37 35 34 33 32"
rem set "tempMem4=5378"
set "memSum=0"
if not defined memRem set "memRem=!maxMem!"

for /l %%N in (1 1 %cycleCount%) DO (set "tempProc%%N=")
for /l %%N in (1 1 %cycleCount%) DO (
  set memRem
  set /a "tempProc%%N=%memRem%/tempMem%%N"
  set /a "memSum+=tempMem%%N"
  set /a "memRem-=tempMem%%N"
  set /a "maxProc=!tempProc%%N!"
  call :executeCycle
  set /a "memRem+=tempMem%%N"
  set /a "memSum-=tempMem%%N"
  set /a "maxProc-=!tempProc%%!
)
goto :fim

:executeCycle
set "lock=lock_%random%_"
set /a "startCount=0, endCount=0"
for /l %%N in (1 1 %maxProc%) DO set "endProc%%N="

    set launch=1
    for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO (
      set "cmd=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t"
      if !startCount! lss %maxProc%  (
        set /a "startCount+=1, nextProc=startCount"
      ) else (
        call :wait
      )
      set cmd!nextProc!=!cmd!
      echo !time! - proc!nextProc!: starting !cmd!
      2>nul del %lock%!nextProc!
      start /b /low cmd /c !cmd!>"%lock%!nextProc!"
    )
    set "launch="
:wait
        for /l %%N in (1 1 %startCount%) do (
          if not defined endProc%%N if exist "%lock%%%N" (
            echo !time! - proc%%N: finished !cmd%%N!
            if defined launch (
              set nextProc=%%N
              exit /b
            )
            set /a "endCount+=1, endProc%%N=1"
          ) 9>>"%lock%%%N"
        ) 2>nul
        if %endCount% lss %startCount% (
        1>nul 2>nul ping /n 2 ::1
        goto :wait
      )

2>nul del %lock%*
echo ===
echo Thats all folks!
exit /b
:fim
pause

我遇到了问题cycleFor1并且部分cycleCmd1位于:cycle1- 他们应该替换 中的for行和第一个cmd变量:executeCycle,以使其按我的意图工作。我怎么做?

我遇到的另一个问题是关于tempMem3. 我已经记录了命令cycleCmd3运行时所需的所有内存。它取决于字典。tempMem3 和 cycleCmd3 相关如下:

for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO
set "tempMem3=1055 799 543 415 287 223 159 127 95 79 63 55 47 43 39 37 35 34 33 32"

所以 1024m 将使用 1055,768m 将使用 799,依此类推,直到 1m 使用 32。我不知道如何将其转换为脚本。

任何帮助表示赞赏。

4

2 回答 2

2

我已经发布了一个强大的批处理解决方案,该解决方案在Parallel execution of shell processes中限制了并行进程的数量。该脚本使用嵌入在脚本中的命令列表。按照链接查看它是如何工作的。

根据您的问题,我修改了该脚本以使用 FOR 循环生成命令。我还将限制设置为 8 个同时进程。

你的最大内存是 1g,而且你的进程永远不会超过 8 个,所以我看不出你怎么能超过 8g。如果您增加每个进程的最大内存,那么您确实需要担心总内存。您将不得不添加额外的逻辑来跟踪正在使用的内存量以及可用的 cpu ID。请注意,批号限制为~2g,因此我建议以兆字节为单位计算内存。

默认情况下,脚本隐藏命令的输出。如果要查看输出,请使用该/O选项运行它。

@echo off
setlocal enableDelayedExpansion

:: Display the output of each process if the /O option is used
:: else ignore the output of each process
if /i "%~1" equ "/O" (
  set "lockHandle=1"
  set "showOutput=1"
) else (
  set "lockHandle=1^>nul 9"
  set "showOutput="
)

:: Define the maximum number of parallel processes to run.
:: Each process number can optionally be assigned to a particular server
:: and/or cpu via psexec specs (untested).
set "maxProc=8"

:: Optional - Define CPU targets in terms of PSEXEC specs
::           (everything but the command)
::
:: If a cpu is not defined for a proc, then it will be run on the local machine.
:: I haven't tested this feature, but it seems like it should work.
::
:: set cpu1=psexec \\server1 ...
:: set cpu2=psexec \\server1 ...
:: set cpu3=psexec \\server2 ...
:: etc.

:: For this demo force all cpu specs to undefined (local machine)
for /l %%N in (1 1 %maxProc%) do set "cpu%%N="

:: Get a unique base lock name for this particular instantiation.
:: Incorporate a timestamp from WMIC if possible, but don't fail if
:: WMIC not available. Also incorporate a random number.
  set "lock="
  for /f "skip=1 delims=-+ " %%T in ('2^>nul wmic os get localdatetime') do (
    set "lock=%%T"
    goto :break
  )
  :break
  set "lock=%temp%\lock%lock%_%random%_"

:: Initialize the counters
  set /a "startCount=0, endCount=0"

:: Clear any existing end flags
  for /l %%N in (1 1 %maxProc%) do set "endProc%%N="

:: Launch the commands in a loop
  set launch=1
  echo mem=1m 2m 3m 4m 6m 8m 12m 16m 24m 32m 48m 64m 96m 128m 192m 256m 384m 512m 768m 1024m
  echo o=2 3 4 5 6 7 8 10 12 14 16 20 24 28 32
  echo s=off 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1g 2g 4g 8g 16g 32g 64g on
  echo x=1 3 5 7 9
  for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO (
    set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s"
    if !startCount! lss %maxProc% (
      set /a "startCount+=1, nextProc=startCount"
    ) else (
      call :wait
    )
    set cmd!nextProc!=!cmd!
    if defined showOutput echo -------------------------------------------------------------------------------
    echo !time! - proc!nextProc!: starting !cmd!
    2>nul del %lock%!nextProc!
    %= Redirect the lock handle to the lock file. The CMD process will     =%
    %= maintain an exclusive lock on the lock file until the process ends. =%
    start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd!
  )
  set "launch="

:wait
:: Wait for procs to finish in a loop
:: If still launching then return as soon as a proc ends
:: else wait for all procs to finish
  :: redirect stderr to null to suppress any error message if redirection
  :: within the loop fails.
  for /l %%N in (1 1 %startCount%) do (
    %= Redirect an unused file handle to the lock file. If the process is    =%
    %= still running then redirection will fail and the IF body will not run =%
    if not defined endProc%%N if exist "%lock%%%N" (
      %= Made it inside the IF body so the process must have finished =%
      if defined showOutput echo ===============================================================================
      echo !time! - proc%%N: finished !cmd%%N!
      if defined showOutput type "%lock%%%N"
      if defined launch (
        set nextProc=%%N
        exit /b
      )
      set /a "endCount+=1, endProc%%N=1"
    ) 9>>"%lock%%%N"
  ) 2>nul
  if %endCount% lss %startCount% (
    1>nul 2>nul ping /n 2 ::1
    goto :wait
  )

2>nul del %lock%*
if defined showOutput echo ===============================================================================
echo Thats all folks!
于 2013-10-20T18:35:58.517 回答
1

要同时执行不超过 8 个7z.exe进程实例,您可以这样做:

@Echo OFF & Setlocal EnableDelayedExpansion

Set /A "pCount=0" & REm Process count

For
...
) DO (
     Set /A "pCount+=1"
     If !pCount! LEQ 8 (
       Start /B 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s
     )
)
...

如果您想在新的并行 CMD 窗口中运行每个进程,那么您可以将Start /B我的代码中的行替换为 else:

CMD /C "Start /w 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s"
于 2013-10-18T20:59:58.233 回答