Windows多线程FOR批处理命令


11

您是否知道是否有一种简单的方法可以在多个线程的批处理文件中运行FOR命令?如果我不能在4个并行线程中运行任务,那么拥有4个内核有什么意义?

例如,如果我要使用PNGOUT优化PNG,我将使用的命令是

for %i in (*.png) do pngout "%i"

但这是高度可并行化的任务,其中子任务完全不依赖。

要在4个“队列”中运行此命令,我会写类似

for -thread 4 %i in (*.png) do pngout "%i"

我是否需要编写自己的for-like应用程序就能做到这一点,还是有免费的解决方案?


检查以下有关使用外部工具的答案:​​[ stackoverflow.com/a/12041213/365229] [1] [1]:stackoverflow.com/a/12041213/365229
Behrouz.M 2015年

Answers:


13

我写了一个批处理文件,该文件仅在不久前在Stack Overflow上执行最大数量的命令:Shell进程的并行执行

@echo off
for /l %%i in (1,1,20) do call :loop %%i
goto :eof

:loop
call :checkinstances
if %INSTANCES% LSS 5 (
    rem just a dummy program that waits instead of doing useful stuff
    rem but suffices for now
    echo Starting processing instance for %1
    start /min wait.exe 5 sec
    goto :eof
)
rem wait a second, can be adjusted with -w (-n 2 because the first ping returns immediately;
rem otherwise just use an address that's unused and -n 1)
echo Waiting for instances to close ...
ping -n 2 ::1 >nul 2>&1
rem jump back to see whether we can spawn a new process now
goto loop
goto :eof

:checkinstances
rem this could probably be done better. But INSTANCES should contain the number of running instances afterwards.
for /f "usebackq" %%t in (`tasklist /fo csv /fi "imagename eq wait.exe"^|find /v /c ""`) do set INSTANCES=%%t
goto :eof

它最多产生四个并行执行并最小化的新进程。等待时间可能需要调整,具体取决于每个进程的工作量和运行时间。如果您要执行其他操作,则可能还需要调整任务列表正在查找的进程名称。

但是,无法正确计算此批处理产生的进程。一种方法是在批处理(%RANDOM%)的开头创建一个随机数,并创建一个进行处理(或生成处理程序)但可以将其窗口标题设置为参数的助手批处理:

@echo off
title %1
"%2" "%3"

这将是一个简单的批处理,将其标题设置为第一个参数,然后运行第二个参数,第三个作为参数。然后,您可以通过仅选择具有指定窗口标题(tasklist /fi "windowtitle eq ...")的进程来过滤任务列表。这应该工作得相当可靠,并防止出现过多的误报。cmd.exe如果仍然有一些实例在运行,搜索将不是一个好主意,因为这限制了工作进程的池。

您可以%NUMBER_OF_PROCESSORS%用来创建合理的默认数量,以产生多少个实例。

您还可以轻松地对此进行修改以用于psexec远程生成进程(但是这样做不可行,因为您必须在另一台计算机上具有管理员权限并在批处理中提供密码)。但是,您将不得不使用进程名称进行过滤。


这是一些严重的黑魔法!希望我可以投票更多次!
Axarydax 2011年

不,一旦掌握了这些,这就是相当基本的东西;-)
Joey

Win10命令行中不提供命令“ wc”。我还能用什么呢?
PeterCo '18

1
@PeterCo :find /c /v ""
乔伊(Joey)

1

批处理文件用于极其基本的脚本编写,不支持任何类型的多线程。您需要编写自己的实用程序来完成您想要完成的工作。

另外,Windows PowerShell可能提供更多功能,使您更接近目标。

如果只想同时运行多个操作,则可以使用命令start在新窗口中启动PNGOUT实用程序。然后,FOR循环将继续,而无需等待每个操作完成。

修改后的行将如下所示:

for %i in (*.png) do start pngout "%i"

但是,请注意,这将同时为目录中的所有文件有效启动PNGOUT ,这很可能是不希望的。


这是一种幼稚的方法,正如您提到的那样,这可能不是可取的。您只想启动与核心一样多的进程。如果您有4个核心和1,000个文件,则您实际上一次只希望处理4个,直到处理了全部1,000个。如果尝试在4个内核上一次处理所有1,000个磁盘,则计算机将缓慢进行无用的爬网。
Adisak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.