问题描述
作为 Python (3.8.2) 脚本的一部分,我通过命令行在 Windows (10) 中启动了一个程序。该程序运行模拟、导出数据并关闭。我的脚本这样做了数百次。偶尔,cmd 窗口出现但什么也不显示(Windows 程序似乎没有做任何事情)。我正在尝试确定问题出在外部程序还是我的脚本上。
我已经搜索了其他答案,但事实证明子流程世界很难理解。我使用 Python 来处理一些基本的移动/解释数据。我看到了这个答案 (Understanding Popen.communicate),其中包括
这似乎很相关,但我无法理解和实施它。
我的功能是:
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
子进程卡住有什么明确的原因吗? (我不知道正确的术语是阻塞还是挂起)。
解决方法
一个可行的解决方案,灵感来自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
我使用 timeout
变量将有关上次运行时间的信息传入/传出函数。