[英]Using subprocess.Popen to start a program in Windows - subprocess sometimes gets stuck - is my script stable?
As part of my Python (3.8.2) script, I start a program in Windows (10) via command line.作为我的 Python (3.8.2) 脚本的一部分,我通过命令行在 Windows (10) 中启动一个程序。 This program runs a simulation, exports data, and closes.
该程序运行模拟、导出数据并关闭。 My script does this hundreds of times.
我的脚本这样做了数百次。 Very occasionally, the cmd window appears but displays nothing (the Windows program does not seem to be doing anything).
偶尔,cmd window 出现但什么也不显示(Windows 程序似乎没有做任何事情)。 I am trying to determine whether the problem is with the external program, or my script.
我正在尝试确定问题出在外部程序还是我的脚本上。
I have searched for other answers but the subprocess world is proving difficult to understand.我已经搜索了其他答案,但事实证明子流程世界很难理解。 I use Python for some basic moving/interpreting data.
我使用 Python 来获取一些基本的移动/解释数据。 I saw this answer ( Understanding Popen.communicate ), which includes
我看到了这个答案( Understanding Popen.communicate ),其中包括
Note: it is a very fragile code if read/write are not in sync;
注意:如果读/写不同步,这是一个非常脆弱的代码; it deadlocks.
它陷入僵局。
This seems relevant but I am not in a position to understand & implement it.这似乎是相关的,但我不在 position 中理解和实施它。
My function is:我的 function 是:
def run_program(args):
cmd = #defined by args
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout, stderr = p.communicate()
variables = #read from some datafiles created by the program that was run
return variables
Is there any clear reason why the subprocess gets stuck?子进程卡住有什么明确的原因吗? (I don't know if the correct term is blocks or hangs).
(我不知道正确的术语是阻塞还是挂起)。
A working solution, with inspiration from How to kill subprocess if no activity in stdout/stderr一个可行的解决方案,灵感来自How to kill subprocess if no activity in stdout/stderr
def run_program(args, timeout):
cmd = [] #defined by args
if timeout == 'default':
timeout = 600
tries = 0
while tries < 4:
tries += 1
try:
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
t = 0
while p.poll() != 0:
if t > timeout:
raise RuntimeError('Timeout')
break
time.sleep(1)
t+=1
successful = True
except RuntimeError:
kill = subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=p.pid))
# some actions for this condition
successful = False
if successful == True:
# some actions for this condition
break
return variables, t
I use the timeout
variable to pass information about the last run time in/out of the function.我使用
timeout
变量将有关上次运行时间的信息传入/传出 function。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.