Python 运行子流程时检查条件

Python 运行子流程时检查条件,python,subprocess,Python,Subprocess,我正在使用subprocess.Popen()执行一个命令。我希望在执行其余代码之前等待进程完成,但同时我希望在运行子进程2分钟后检查生成文件的状态。如果文件大小为零,则我要停止该过程。目前我的代码如下。有没有更聪明的方法 def execute(command,outputfilename): process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) start

我正在使用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结果转换为整数。保持所有浮动应该可以进行比较,这都是基本的机器逻辑
  • 当process.returncode不是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()
                    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()
        ...