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

5 投票
2 回答
6751 浏览
提问于 2025-04-16 09:21

好的,我现在遇到的问题是这样的:

我需要运行一个程序,并设置一些参数,同时检查它的进展,并把结果反馈给一个服务器。所以我希望我的脚本在程序运行时不要被阻塞,但我也需要能够读取程序的输出。不幸的是,我觉得Popen提供的方法似乎无法在不阻塞的情况下读取输出。我试过以下的方法,这有点像是变通的做法(我们可以从两个不同的对象同时读写同一个文件吗?)

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请求,所以用Python似乎比用shell脚本更简单。

谢谢!

Will

2 个回答

2

你可以使用 twisted 这个库来解决这个问题。我觉得它非常适合这个用途。

这里有个示例代码

文档链接:点击这里查看文档

7

基本上,你有三种选择:

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

撰写回答