Python 运行子流程时检查条件
我正在使用subprocess.Popen()执行一个命令。我希望在执行其余代码之前等待进程完成,但同时我希望在运行子进程2分钟后检查生成文件的状态。如果文件大小为零,则我要停止该过程。目前我的代码如下。有没有更聪明的方法Python 运行子流程时检查条件,python,subprocess,Python,Subprocess,我正在使用subprocess.Popen()执行一个命令。我希望在执行其余代码之前等待进程完成,但同时我希望在运行子进程2分钟后检查生成文件的状态。如果文件大小为零,则我要停止该过程。目前我的代码如下。有没有更聪明的方法 def execute(command,outputfilename): process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) start
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结果转换为整数。保持所有浮动应该可以进行比较,这都是基本的机器逻辑李>
更改循环条件,可以避免从无限循环中断:…
=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()
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要在2分钟内杀死子进程,如果
outputfilename
为空(我假设outputfilename
被某个外部进程修改),可以使用线程。计时器
:
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,避免了问题代码中可能出现的死锁。此问题似乎与主题无关,因为它是关于检查工作代码,这与主题无关:使用
is None
与None
进行比较,因为它是一个单例,=
可以被覆盖以返回True
,即使对于非None
对象也是如此。谢谢。我使用了第一个选项
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()
...