Python的select()延迟报告子进程输出的存在

问题描述 投票:0回答:1

我正在运行这个简单的Python程序来合并两个子进程的输出行:

import select
from subprocess import PIPE, Popen
import sys

subprocs = [
    Popen(cmdline, stdout=PIPE) for cmdline in
    [['./repeat', 'abc'], ['./repeat', 'xyz']]
]
while True:
    rstreams, _, _ = select.select([p.stdout for p in subprocs], [], [])
    for stream in rstreams:
        sys.stdout.buffer.write(stream.readline())

…其中repeat是一个定期生成输出的简单脚本:

#!/bin/bash
while sleep 1 ; do echo $@ ; done

我希望将两个子流程的输出逐行合并,以便合并后的输出以任意顺序包含abcxyz的行,并及时进行中继。 (不需要混合数据,例如abxyzc。]

但是,我发现上面的Python程序很长时间没有产生任何输出,或者直到我按下Ctrl C为止。

((我曾尝试将stream.readline()更改为stream.read(1),以防问题是readline()挂起,即使我不希望这种交错,但也无济于事。在Python 3.5中会发生Linux上的.2和macOS上的Python 3.7.6。)

当子流程清楚地产生输出时,select()为什么要等待?

python python-3.x io subprocess polling
1个回答
1
投票
根本原因是您使用的sys.stdout.buffer内部具有缓冲区,因此我们无法立即看到结果。

我们可以在写入后显式刷新结果。将sys.stdout.buffer.flush()放在buffer.write()之后。或者只使用print(stream.readline())而不是sys.stdout.buffer

© www.soinside.com 2019 - 2024. All rights reserved.