Работа вокруг ограничения 32 окна в MinGW (Windows пакетных файлов) - PullRequest
0 голосов
/ 11 марта 2020

Я вычислительный биолог и пытаюсь запускать большие партии похожего кода с помощью одной команды, но моя реализация попала в кирпичную стену.

Я использую среду моделирования NEURON, который использует MinGW для своего Windows интерфейса, и именно здесь мое исследование показало, что у меня возникает проблема.

В настоящее время я использую командный файл для запуска всех этих похожих фрагментов кода, для итерации по " коллекция "подпапок:

@echo off
for /D %%a in ("%cd%\all_cells\cell_*.*") do cd "%%a\sim1\" & START neuron sim.hoc

Проблема возникает, когда у меня более 32 подпапок; дополнительные экземпляры не будут запущены и приведут к ошибке «Ошибка выделения консольного устройства: слишком много консолей».

Мои исследования показали, что это известная проблема с Cygwin / MinGW.

Тем не менее, работа вокруг этого вручную (при условии, что не более 32 папок «коллекции») занимает очень много времени, когда я имею дело с сотнями экземпляров (каждый относится к моделируемой ячейке, и я хочу собрать статистику по сотням из них), поэтому я пытаюсь найти решение.

Тем не менее, я ужасен в написании командных файлов (я ужасный программист, который привык к c языкам) и я могу ' не могу понять, как обойти это.

Было бы замечательно, если бы кто-нибудь мог помочь мне найти способ преодолеть ограничение 32 или, если это не удалось, помочь мне написать командный файл, который бы делал это:

- переберите до 32 папок - дождитесь завершения экземпляров - делайте это снова в течение следующих 32, пока я не достигну конца папки.

Я пытался использовать команду / wait, чтобы выполнять их по одному, но все равно открываются все 32. (И это не было бы идеально, поскольку я хотел бы использовать все 16 ядер, которые у меня есть.

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Следующее значение адаптировано из { ссылка }, в котором показано, как запускать любое количество процессов при ограничении общего числа одновременных параллельных процессов. См. Этот пост для некоторого объяснения, хотя приведенный ниже код довольно хорошо задокументирован с комментариями.

Я исключил параметр / O и код для работы с PSEXE C из исходного сценария.

Сценарий, приведенный ниже, запускает все в одном окне - выходные данные каждого процесса записываются во временный файл блокировки, а после завершения полный вывод каждого процесса выводится на экран без чередования выходных данных процесса. Время начала и окончания каждого процесса также отображаются. Конечно, вы можете перенаправить вывод основного сценария, если хотите записать все в один файл.

Я ограничил общее количество параллельных процессов до 16 - конечно, вы можете легко изменить это ограничение.

Код не будет работать так, как написано, если любой из путей к вашим папкам содержит символ !. Это можно исправить с помощью небольшого количества дополнительного кода.

Кроме этого, код должен работать, если я не допустил глупых ошибок. Я не тестировал этот сценарий, хотя сценарий, на основе которого он был создан, был тщательно протестирован.

@echo off
setlocal enableDelayedExpansion

:: Define the maximum number of parallel processes to run.
set "maxProc=16"

:: 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
  for /D %%A in ("%cd%\all_cells\cell_*.*") do (
    if !startCount! lss %maxProc% (
      set /a "startCount+=1, nextProc=startCount"
    ) else (
      call :wait
    )
    set "cmd!nextProc!=%%A"
    echo -------------------------------------------------------------------------------
    echo !time! - proc!nextProc!: starting %%A
    2>nul del %lock%!nextProc!

    cd "%%A\sim1\"

    %= Redirect the output to the lock file and execute the command. The CMD process =%
    %= will maintain an exclusive lock on the lock file until the process ends.      =%
    start /b "" cmd /c 1^>"%lock%!nextProc!" 2^>^&1 neuron sim.hoc
  )
  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 2>nul (
    %= 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" 9>>"%lock%%%N" (
      %= Made it inside the IF body so the process must have finished =%
      echo ===============================================================================
      echo !time! - proc%%N: finished !cmd%%N!
      type "%lock%%%N"
      if defined launch (
        set nextProc=%%N
        exit /b
      )
      set /a "endCount+=1, endProc%%N=1"
    )
  )
  if %endCount% lss %startCount% (
    timeout 1 /nobreak >nul
    goto :wait
  )

2>nul del %lock%*
echo ===============================================================================
echo Thats all folks^^!
0 голосов
/ 11 марта 2020

Вы можете установить screen или tmux в cygwin.

Затем вы можете запустить все экземпляры нейронов в сеансе screen / tmux.
Они не откроют новое окно, поэтому ограничений больше нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...