等待 python 中的子进程创建其他进程
Waiting for a sub process in python which creates other processes
我正在使用 python 使用 "RunDirMulti.bat" 启动 EnergyPlus 批量模拟。此 bat 文件为目录中的每个模拟文件创建一个进程。
RunDirMulti 看起来像这样:
@echo off
: This batch file is used to run EnergyPlus simulations using the RunEPlus.bat for all
: the files in the current directory across multiple separate processor cores. It has
: two parameters, the weather file name to use for simulations and the number of
: processors.
:
: RunDirMulti <weather file> (opt) <number processor cores> (opt)
:
: The RunDirMulti batch file loops through the files located in the current directory
: and puts RunEPlus calls to each file into as many temporary batch files as processor
: cores and then starts each of the batch files. No load balancing between the cores
: is achieved using this method. The RunDirMulti.bat file should be located in a
: directory that contains the IDF files.
: Main routine
: maindir - change if you did not install in default folder (to be safe, use quotes)
SET maindir="E:\PROGRAMAS\EnergyPlusV8-4-0\"
: The default weather file name if not provided as an argument.
SET weather=ECU_Quito.840710_IWEC
: The default number of separate processor cores that the simulations should use if
: not provided as an argument.
SET numProc=4
IF "%1" NEQ "" SET weather=%1
IF "%2" NEQ "" SET numProc=%2
SET count=0
: Loop through the temporary directories and delete the temporary batch files.
for /L %%G in (1,1,%numProc%) do call :clean1 %%G
: Loop through each filename and divides them into each temporary batch file.
for %%F in (.\*.idf) do call :divide1 "%%F"
: Loop through each temporary directory and adds EXIT to each temporary batch file.
for /L %%G in (1,1,%numProc%) do echo EXIT >> .\tempsim%%G\simpart%%G.bat
: Loop through each temporary directory and starts the batch file in a new window
for /L %%G in (1,1,%numProc%) do call :startEach1 %%G
: The following line goes to the end of the batch file.
GOTO:eof
: Subroutine that deletes the temporary batch files from each
: working directory.
:clean1
IF EXIST .\tempsim%1\simpart%1.bat (
DEL .\tempsim%1\simpart%1.bat
) ELSE (
MD .\tempsim%1
)
: The following line returns to the main routine.
GOTO:eof
: Subroutine that takes the file name and uses a counter
: and the MOD operator (double percent) to group them
: into as many batch files as necessary.
:divide1
SET /a count="count + 1"
SET /a group="count %% numProc + 1"
echo CALL %maindir%RunEPlus.bat "%~dpn1" %weather% >>.\tempsim%group%\simpart%group%.bat
: The following line returns to the main routine.
GOTO:eof
: Subroutine that starts each batch file
:startEach1
cd .\tempsim%1
START "Batch Simulation%1" simpart%1.bat
cd ..
: The following line returns to the main routine.
GOTO:eof
在我的脚本中,我使用这个
p=subprocess.check_call("RunDirMulti.bat")
但它不会等待所有子进程完成。我已经尝试过 Popen 和 Popen.wait()。有人可以给我一个想法吗?
该过程完成后,您可以通过批处理脚本输出完成的文件:
type NUL > done.txt
然后将如下内容添加到您的 python 脚本中
import os
import time
done_file_path = r'C:\Users\user\done.txt'
while not os.path.exists(done_file_path):
print "Done file not created, Sleeping for 10 seconds"
time.sleep(10) # Sleep 10 second
os.remove(done_file_path) # Remove Done file, so next run is successful
将路径 (C:\Users\user\done.txt) 调整到您当然要输出完成文件的位置。
解决了它创建一个检查 cmd 是否打开的函数(在我的情况下,我是 运行 ipython 笔记本,所以已经有一个 cmd 一直打开)。
def running():
n=0 #number of cmd instances running
prog=[line.split() for line in subprocess.check_output("tasklist").splitlines()]
[prog.pop(e) for e in [0,1,2]] #useless
for task in prog:
if task[0]=="cmd.exe":
n=n+1
if n>1:
return True
else:
return False
这应该适用于任何程序。
我正在使用 python 使用 "RunDirMulti.bat" 启动 EnergyPlus 批量模拟。此 bat 文件为目录中的每个模拟文件创建一个进程。 RunDirMulti 看起来像这样:
@echo off
: This batch file is used to run EnergyPlus simulations using the RunEPlus.bat for all
: the files in the current directory across multiple separate processor cores. It has
: two parameters, the weather file name to use for simulations and the number of
: processors.
:
: RunDirMulti <weather file> (opt) <number processor cores> (opt)
:
: The RunDirMulti batch file loops through the files located in the current directory
: and puts RunEPlus calls to each file into as many temporary batch files as processor
: cores and then starts each of the batch files. No load balancing between the cores
: is achieved using this method. The RunDirMulti.bat file should be located in a
: directory that contains the IDF files.
: Main routine
: maindir - change if you did not install in default folder (to be safe, use quotes)
SET maindir="E:\PROGRAMAS\EnergyPlusV8-4-0\"
: The default weather file name if not provided as an argument.
SET weather=ECU_Quito.840710_IWEC
: The default number of separate processor cores that the simulations should use if
: not provided as an argument.
SET numProc=4
IF "%1" NEQ "" SET weather=%1
IF "%2" NEQ "" SET numProc=%2
SET count=0
: Loop through the temporary directories and delete the temporary batch files.
for /L %%G in (1,1,%numProc%) do call :clean1 %%G
: Loop through each filename and divides them into each temporary batch file.
for %%F in (.\*.idf) do call :divide1 "%%F"
: Loop through each temporary directory and adds EXIT to each temporary batch file.
for /L %%G in (1,1,%numProc%) do echo EXIT >> .\tempsim%%G\simpart%%G.bat
: Loop through each temporary directory and starts the batch file in a new window
for /L %%G in (1,1,%numProc%) do call :startEach1 %%G
: The following line goes to the end of the batch file.
GOTO:eof
: Subroutine that deletes the temporary batch files from each
: working directory.
:clean1
IF EXIST .\tempsim%1\simpart%1.bat (
DEL .\tempsim%1\simpart%1.bat
) ELSE (
MD .\tempsim%1
)
: The following line returns to the main routine.
GOTO:eof
: Subroutine that takes the file name and uses a counter
: and the MOD operator (double percent) to group them
: into as many batch files as necessary.
:divide1
SET /a count="count + 1"
SET /a group="count %% numProc + 1"
echo CALL %maindir%RunEPlus.bat "%~dpn1" %weather% >>.\tempsim%group%\simpart%group%.bat
: The following line returns to the main routine.
GOTO:eof
: Subroutine that starts each batch file
:startEach1
cd .\tempsim%1
START "Batch Simulation%1" simpart%1.bat
cd ..
: The following line returns to the main routine.
GOTO:eof
在我的脚本中,我使用这个
p=subprocess.check_call("RunDirMulti.bat")
但它不会等待所有子进程完成。我已经尝试过 Popen 和 Popen.wait()。有人可以给我一个想法吗?
该过程完成后,您可以通过批处理脚本输出完成的文件:
type NUL > done.txt
然后将如下内容添加到您的 python 脚本中
import os
import time
done_file_path = r'C:\Users\user\done.txt'
while not os.path.exists(done_file_path):
print "Done file not created, Sleeping for 10 seconds"
time.sleep(10) # Sleep 10 second
os.remove(done_file_path) # Remove Done file, so next run is successful
将路径 (C:\Users\user\done.txt) 调整到您当然要输出完成文件的位置。
解决了它创建一个检查 cmd 是否打开的函数(在我的情况下,我是 运行 ipython 笔记本,所以已经有一个 cmd 一直打开)。
def running():
n=0 #number of cmd instances running
prog=[line.split() for line in subprocess.check_output("tasklist").splitlines()]
[prog.pop(e) for e in [0,1,2]] #useless
for task in prog:
if task[0]=="cmd.exe":
n=n+1
if n>1:
return True
else:
return False
这应该适用于任何程序。