batch-file - 在 MinGW 中处理 32 个窗口限制(Windows 批处理文件)
问题描述
我是一名计算生物学家,我正在尝试使用单个命令运行大量类似的代码,但我的实现遇到了障碍。
我正在使用 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 个“集合”文件夹)非常耗时),所以我正在努力寻找解决方案。
也就是说,我在编写批处理文件方面很糟糕(我是一个习惯于科学语言的糟糕程序员),我不知道如何围绕这个编写代码。
如果有人可以帮助我找到绕过 32 个限制的方法,或者如果失败了,帮助我编写一个可以执行此操作的批处理文件,那就太好了:
- 迭代多达 32 个文件夹 - 等待实例完成 - 在接下来的 32 个文件夹中再做一次,直到我到达文件夹的末尾。
我曾尝试使用 /wait 命令一次执行一个,但它仍然会打开所有 32 个。(这并不理想,因为我想使用我拥有的所有 16 个内核。
解决方案
以下内容改编自https://stackoverflow.com/a/11715437/1012053,展示了如何运行任意数量的进程,同时限制并行同时运行的总数。请参阅该帖子以获得一些解释,尽管下面的代码已经很好地记录了注释。
我已经从原始脚本中删除了 /O 选项和使用 PSEXEC 的代码。
下面的脚本在一个窗口中运行所有内容 - 每个进程的输出都被捕获到一个临时锁定文件中,完成后,每个进程的完整输出都被输入到屏幕上,没有任何进程输出交错。还会显示每个过程的开始和结束时间。当然,如果您想将所有内容捕获到单个文件中,您可以重定向主脚本的输出。
我将并行进程的总数限制为 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^^!
推荐阅读
- s4sdk - 错误:找不到文件 /home/vcap/app/xs-app.json
- python - python-从变量中读取一定数量的字节
- go - 是否有任何标准协议可以通过网络传输 RSA 加密文本?
- java - 有没有办法在加载时使用来自先前场景的数据填充场景,而不必启动事件?
- java - 如何在 Gradle 中修复我的 React Native 失败的 Android 构建?com.google.firebase:firebase-iid 正在被其他各种库请求
- javascript - 无法使用窗口 onload 方法加载我的图表
- angular - 如何将用户引导到页面的特定部分?
- python - 如何删除json中的“行继续字符后的意外字符”SyntaxError?
- sql - 从另一个表的 3 个不同列的表中获取连接的 desc
- android - 如何设置由于不同设备上的背景图像而扩展的滚动视图?