簡體   English   中英

運行子流程時檢查條件

[英]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()

在全球范圍內,您的代碼對我來說看起來不錯。 只有一些細節:

  1. (time.time()-start_time)//60>1 ,我認為//沒用,因為您不一定需要舍棄結果並將除法lhs的結果轉換為整數。 比較起來應該保持所有浮動,這是所有基本的機器邏輯;
  2. 您可以通過使用while process.returncode is not None:…來更改循環條件來避免從無限循環中中斷while process.returncode is not None:…
  3. 為了使它更簡單,我實際上要循環直到文件大小為!=0 ,然后在循環之后調用process.wait()
  4. 這將是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM