Python:非阻塞子进程,检查标准输出

5

好的,我要解决的问题是:

我需要运行一个带有一些标志的程序,检查其进度并向服务器报告。因此,我需要我的脚本在程序执行时避免阻塞,但我也需要能够读取输出。不幸的是,我认为Popen提供的所有方法都无法在没有阻塞的情况下读取输出。我尝试了以下方法,这有点hack-y(我们可以从两个不同的对象读写同一个文件吗?)

import time
import subprocess
from subprocess import *
with open("stdout.txt", "wb") as outf:
    with open("stderr.txt", "wb") as errf:
        command = ['Path\\To\\Program.exe', 'para', 'met', 'ers']
        p = subprocess.Popen(command, stdout=outf, stderr=errf)
        isdone = False
        while not isdone :
            with open("stdout.txt", "rb") as readoutf: #this feels wrong
                for line in readoutf:
                    print(line)
            print("waiting...\\r\\n")
            if(p.poll() != None) :
                done = True
            time.sleep(1)
        output = p.communicate()[0]    
        print(output)

不幸的是,Popen似乎只有在命令终止之后才会写入到我的文件中。

有人知道如何解决吗?我不一定非要使用Python,但我确实需要在同一个脚本中向服务器发送POST请求,因此与shell脚本相比,Python似乎更容易一些。

谢谢! Will


你确定所涉及的 Program.exe 是否定期刷新 stdout - Daniel DiPaolo
1
你确定你需要那些文件而不是 subprocess.PIPE 吗? - Jochen Ritzel
@THC4k -- 使用管道是可以的,但我找不到一种不阻塞的读取方法。 - Will Cavanagh
@Daniel 当我不通过Python运行命令时,它会在进程中输出到终端。这是你的意思吗? - Will Cavanagh
2个回答

7

基本上你有3个选择:

  1. 使用 threading 在另一个线程中读取,而不会阻塞主线程。
  2. select 在标准输出和标准错误上,而不是使用 communicate。这样你可以在数据可用时读取,避免阻塞。
  3. 让一个库来解决这个问题,twisted 是一个明显的选择


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接