【发布时间】:2021-06-14 05:34:50
【问题描述】:
为什么subprocess.PIPE 阻止被调用的可执行文件关闭。
我使用以下脚本调用具有多个输入的可执行文件:
import subprocess, time
CREATE_NO_WINDOW = 0x08000000
my_proc = subprocess.Popen("myApp.exe " + ' '.join([str(input1), str(input2), str(input3)]),
startupinfo=subprocess.STARTUPINFO(), stdout=subprocess.PIPE,
creationflags = CREATE_NO_WINDOW)
然后我监控应用程序是否在给定时间(300 秒)内完成,如果没有,我就将其终止。我还阅读了应用程序的输出,以了解它是否未能完成所需的任务。
proc_wait_time = 300
start_time = time.time()
sol_status = 'Fail'
while time.time() - start_time < proc_wait_time:
if (my_proc.poll() is None):
time.sleep(1)
else:
try:
sol_status = my_proc.stdout.read().replace('\r\n \r\n','')
break
except:
sol_status = 'Fail'
break
else:
try: my_proc.kill()
except: None
sol_status = 'Frozen'
if sol_status in ['Fail', 'Frozen']:
print ('Failed running my_proc')
您可以从代码中注意到,我需要等待 myApp.exe 完成,但是,有时 myApp.exe 会冻结。由于上面的脚本是循环的一部分,我需要(通过计时器)识别这种情况,跟踪它并杀死myApp.exe,这样整个脚本就不会卡住!
现在,问题是如果我使用subprocess.PIPE(如果我想读取应用程序的输出,我想我必须这样做)然后myApp.exe 在完成后不会关闭,因此my_proc.poll() is None 总是 True .
我使用的是 Python 2.7。
【问题讨论】:
-
杀死应用程序时是否正在关闭管道?
-
不,这都是在
my_proc方面,我怎样才能显式关闭 PIPE?我需要在kill()之后立即执行吗?我一直认为这是集成在kill中的。另外,如何解决my_proc.poll() is None一直为真的问题? -
如果您不是从管道读取数据,并且进程向其写入的数据超过缓冲区(可能是 4K),那么它将阻塞,直到一些缓冲区空间可用 - 这永远不会发生.
-
@jasonharper 那么解决方法是
stdout.read()每隔一段时间就合并一次吗? -
@Mosy:
stderr有什么东西吗?returncode呢?如果您使用subprocess.Popen('taskkill /F /T /PID %i' % my_proc.pid)而不是my_proc.kill()会发生什么?将标准输出直接通过管道传输到文件中:subprocess.Popen("myApp.exe, ..., stdout=open("C:/temp/whatever.log", 'w').open())
标签: python python-2.7 subprocess