避免子进程.Popen的标准输出管道阻塞并冻结子进程

时间:2018-09-12 14:10:12

标签: python popen

我有一个用例,当我需要启动一个进程(IIS Express Web服务器),等到它打印出某一行以确保它已完全初始化,然后停止读取其输出并运行一些其他阻止操作时: / p>

proc = subprocess.Popen('iisexpress.exe /path:<bla bla bla>', shell=True, stdout=subprocess.PIPE);
# .... <read some output>
os.system('nunit <bla bla bla>') # This takes a long time

问题是我停止读取输出管道,但是子进程没有停止对其进行写入。最终,管道被填满,并且子进程在尝试对其进行写操作时冻结。

我正在考虑2种方法-在我的Python脚本中启动一个新线程以读取和丢弃子进程中的行,或者找到某种方法将管子重定向到/dev/null,它。

我应该采用哪种方法?

1 个答案:

答案 0 :(得分:2)

您将必须阅读第一个过程中的所有内容。您可以通过分叉自己并阅读(并忘记)子进程中的所有内容或拆分一个单独的线程来完成此操作。我希望使用线程方法:

import threading

proc = subprocess.Popen('iisexpress.exe /path:<bla bla bla>',
                        shell=True, stdout=subprocess.PIPE)

# now wait for the trigger line:
while trigger not in proc.stdout.readline():
    pass

# start a thread for reading the rest:
def read_and_drop():
    while proc.stdout.readline():
        pass

threading.Thread(target=read_and_drop)

# here start the other process:
os.system('nunit <bla bla bla>')

我假设第一个进程将逐行打印其输出。如果改为打印出4TB的文本而没有换行符,则该文本将无法正常工作(因为线程尝试读取完整的行)。如果这对您来说是一个问题,请发表评论,然后我也可以提供一个可读性稍差,版本较长的版本来解决这个问题。