Windows批处理文件和多个处理器

时间:2015-09-05 05:57:44

标签: windows multithreading batch-file multiprocessing

我有一个Windows批处理文件,除多个文件外,多次执行相同的操作。有没有办法告诉计算机使用不同的处理器内核来加速这个过程?否则,由于始终使用相同的处理器,因此需要更长的时间。

2 个答案:

答案 0 :(得分:1)

虽然批处理文件可以启动多个并行线程,但是存在与所有这些线程的同步相关的多个问题。通常的同步方法使用像信号量这样的文件,但检查信号量文件的代码会浪费CPU时间。虽然可以在此代码中插入延迟,但结果通常很麻烦且很棘手。

我为批处理文件开发了一种高效的多线程方案,使用管道获取同步信号;这一点允许等待代码不浪费CPU时间,因此所有CPU内核都可用于数据处理。下面的程序是一个处理通配符选择的几个文件的例子,但是这个代码可以很容易地适用于处理任何其他数据集;此方法专门针对仅一个线程同时结束其处理并且如果两个或多个文件的处理在非常短的时间间隔内以可能失败的情况而设计。

@echo off
setlocal EnableDelayedExpansion

rem Multi-thread scheme in Batch files
rem Antonio Perez Ayala aka Aacini

set "myID=%~2"
if "%~1" neq "" goto %1

set "signal=X"
for /L %%i in (1,1,10) do set "signal=!signal!!signal!"

rem Create the list of start commands for the concurrent working threads
set "numThreads=%NUMBER_OF_PROCESSORS%"
set "threads="
del availableThread* 2> NUL
for /L %%i in (1,1,%numThreads%) do (
   set "threads=!threads! & start "" /B cmd /C "%~NX0" Thread %%i"
   > availableThread%%i echo %%i
)

echo Start of application
del requestForThread* 2> NUL
( %threads:~3% ) | "%~NX0" Main
echo End of application
goto :EOF


:Main

echo Main - started

rem Controlling code: process all files and assign each one to available threads
for /F "delims=" %%f in ('dir /A-D /B *.txt') do (

   rem Get the number of next available thread; waits for anyone, if necessary
   if not exist availableThread* (
      echo X > mainIsWaiting
      echo Main - waiting for an available thread
      set /P availableSignal=
      del mainIsWaiting
   )

   set "nextThread="
   for %%t in (availableThread*) do if not defined nextThread (
      set /P "nextThread=" < %%t
      del %%t
   )

   if not defined nextThread (
      echo SYNCHRO FAILED^^!
      goto waitThreadsEnds
   )

   rem Assign the next file to the available thread
   echo %%f> requestForThread!nextThread!
   echo Main - file "%%f" assigned to thread #!nextThread!

)

echo Main - all files sent to processing

rem Wait until all threads ends their tasks
:waitThreadsEnds
   set availableThreads=0
   for %%t in (availableThread*) do set /A availableThreads+=1
if %availableThreads% lss %numThreads% goto :waitThreadsEnds
del availableThread*

rem Send "exit" signals to all threads
for /L %%i in (1,1,%numThreads%) do echo exit> requestForThread%%i
echo Main - end
goto :EOF


:Thread

rem Wait until a request for this thread appear
if not exist requestForThread%myID% goto Thread
set "request="
set /P "request=" < requestForThread%myID%
if not defined request goto Thread
del requestForThread%myID%
if "%request%" equ "exit" goto :EOF

rem Process the file
echo %time% - Thread #%myID% start: "%request%" > CON
set /A seconds=6+%random:~-1%
ping localhost -n %seconds% > NUL
echo %time% - Thread #%myID% end:   "%request%" > CON

rem Inform that this thread is available for other task
> availableThread%myID% echo %myID%
if exist mainIsWaiting echo %signal:~0,1021%

goto Thread

当然,为了使此方法按预期工作,您的Windows计算机必须单独处理此批处理文件,而不需要其他并发进程。

有关此解决方案中使用的方法的进一步说明,请参阅this post

答案 1 :(得分:0)

在Windows批处理文件中,您可以使用多线程管道或start /b

这样的事情应该有效

@echo off
setlocal EnableDelayedExpansion
set "file1=%~1"

:startExtraThread
if NOT "%~2"=="" (
  start "Thread for %~2" /b "cmd /c %~f0 %~2"
  shift
  goto :startExtraThread
)

do my job with file1