[英]Check a condition while running subprocess
我正在使用subprocess.Popen()执行命令。 我想在执行其余代码之前等待进程完成,但是同时我想在运行子进程2分钟后检查生成的文件的状态。 如果文件大小为零,那么我想停止该过程。 目前,我的代码如下。 有没有更聪明的方法可以做到这一点?
def execute(command,outputfilename):
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
start_time=time.time()
Is_Working=False
while True:
process.poll()
if not Is_Working:
#allow 2 minutes for the process to create results
if process.returncode == None and (time.time()-start_time)//60>1:
Is_Working=True
if (os.stat(outputfilename)[6]==0):
process.kill()
return
if process.returncode != None:
break
output, errors=process.communicate()
在全球范围内,您的代码对我来说看起来不错。 只有一些细节:
(time.time()-start_time)//60>1
,我认为//
没用,因为您不一定需要舍弃结果并将除法lhs的结果转换为整数。 比较起来应该保持所有浮动,这是所有基本的机器逻辑; while process.returncode is not None:…
来更改循环条件来避免从无限循环中中断while process.returncode is not None:…
!=0
,然后在循环之后调用process.wait()
。 while/else
构造的好方案 因此,有一个改进是,您可以在过程完成之后(无论成功还是失败)进行处理(例如清理或重试...):
def execute(command,outputfilename):
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
start_time=time.time()
Is_Working=False
while process.returncode == None:
process.poll()
#allow 2 minutes for the process to create results
if (time.time()-start_time)/60 > 1:
if (os.stat(outputfilename)[6]==0):
process.kill()
break
else:
# the process has not been killed
# wait until it finishes
process.wait()
output, errors=process.communicate()
# do stuff with the output
[…]
# here the process may have been killed or not
[…]
或另一个好的选择是引发异常:
def execute(command,outputfilename):
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
start_time=time.time()
Is_Working=False
while process.returncode == None:
process.poll()
#allow 2 minutes for the process to create results
if (time.time()-start_time)/60 > 1:
if (os.stat(outputfilename)[6]==0):
process.kill()
raise Exception("Process has failed to do its job")
# the process has not been killed
# wait until it finishes
process.wait()
output, errors=process.communicate()
# do stuff with the output
[…]
HTH
要在outputfilename
为空的情况下在2分钟内杀死子进程(我假设outputfilename
被某个外部进程修改了),则可以使用threading.Timer
:
import os
from subprocess import Popen, PIPE
from threading import Timer
def kill_if_empty(proc, filename):
if proc.poll() is None and os.path.getsize(filename) == 0:
proc.kill()
def execute(command, outputfilename):
p = Popen(command, stdout=PIPE, stderr=PIPE)
Timer(2*60, kill_if_empty, [p, outputfilename]).start()
output, errors = p.communicate()
...
此代码分别收集stdout / stderr,并且避免了问题代码中可能出现的死锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.