Python子进程stdout迭代器总是阻塞

时间:2017-07-06 16:45:10

标签: python

我希望在打印时捕获输出,但是我不会在没有读取任何一行的情况下永久阻止输出。 发生了什么?我正在使用Python2。

生成器脚本:

#!/usr/bin/env python2.7

import random
import time

while True:
    print(random.random())
    time.sleep(1)

样本生成器输出:

$ ./generator.py 
0.334835137212
0.896609571236
0.833267988558
0.55456332113
^CTraceback (most recent call last):

读者脚本:

import subprocess

cmd = ['./generator.py']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)

for line in p.stdout:
    print(line)
    print('Looping')

p.wait()

我也尝试过:

import subprocess
import sys

cmd = ['./generator.py']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)

while True:
    line = p.stdout.readline()
    print(line)

    print('Looping')

p.wait()

...和

import sys
import subprocess
import select
import time

cmd = ['./generator.py']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)

s = select.poll()
s.register(p.stdout, select.POLLIN)

while True:
    if s.poll(1):
        line = p.stdout.read()
    else:
        p.poll()
        if p.returncode is not None:
            break

    print('Looping')
    time.sleep(1)

p.wait()

2 个答案:

答案 0 :(得分:0)

正如@dhke所提到的,其中一个问题是生产者中的隐式输出缓冲。如果您有能力更改制作人,并且您愿意,通过调用print-function完成制作,那么只需添加" flush = True&#34 ;作为print函数的参数。您还可以回退到制作人的关键点sys.stdout.flush()

第二个问题似乎是在sys.stdout上进行迭代。这似乎永远不适用于长期运行的过程。第二种和第三种方法

答案 1 :(得分:0)

我正在处理类似的问题。这是我目前用来防止缓冲的变通方法。

proc = subprocess.Popen(['stdbuf', '-o0'] + cmd, stdout=subprocess.PIPE)

这种方法的缺点是它依赖外部Linux命令来解决问题。查看注释here,了解不同的本地python方法,以摆脱PIPE缓冲。非常感谢@ 9000向我提出两种解决方案。