Python select () задерживает сообщение о наличии вывода из подпроцессов - PullRequest
0 голосов
/ 13 марта 2020

Я запускаю эту простую 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

Я бы хотел, чтобы выходные данные двух подпроцессов были объединены по линиям, чтобы объединенный вывод содержал строки abc и xyz в любом порядке, своевременно передаваемые. (Смешивание данных, таких как abxyzc, нежелательно.)

Однако я обнаружил, что вышеприведенная программа Python не производит никакого вывода в течение очень долгого времени или пока я не нажму Ctrl C.

(я пытался изменить stream.readline() на stream.read(1), если проблема связана с зависанием readline(), хотя я Я не хочу такого чередования, но это не помогло. Случается с Python 3.5.2 на Linux и Python 3.7.6 на macOS.)

Почему select() ожидание, когда подпроцессы явно генерируют вывод?

1 Ответ

1 голос
/ 13 марта 2020

Причина root в том, что вы используете sys.stdout.buffer, у которого есть внутренний буфер, и поэтому мы не смогли сразу увидеть результат.

Мы могли бы явно грипп sh результат после записи. Ставить sys.stdout.buffer.flush() после buffer.write(). Или просто используйте print(stream.readline()) вместо sys.stdout.buffer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...