Como interagir adequadamente com um processo usando o módulo de subprocesso
-
22-07-2019 - |
Pergunta
Estou tendo problemas para redirecionar o stdio de outro programa usando o módulo de subprocesso. Basta ler o Stdout resulta em pendura e popen.communicate () funciona, mas fecha os tubos após a leitura/escrita. Qual é a maneira mais fácil de implementar isso?
Eu estava brincando com isso no Windows:
import subprocess
proc = subprocess.Popen('python -c "while True: print \'Hi %s!\' % raw_input()"',
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while True:
proc.stdin.write('world\n')
proc_read = proc.stdout.readline()
if proc_read:
print proc_read
Solução
Não se encaixa 100% ao seu exemplo, mas ajuda a entender a questão subjacente: o processo P inicia a criança C. Child C escreve algo em seu stdout. O stdout de C é um tubo que possui um buffer de caracteres 4096 e a saída é mais curta que isso. Agora, C espera por alguma entrada. Para C, está tudo bem.
P aguarda a saída que nunca virá porque o sistema operacional não vê motivos para lavar o buffer de saída de C (com tão poucos dados). Como P nunca obtém a saída de C, nunca escreverá nada para C, então C está esperando a entrada de P.
Correção: Use Flush após cada gravação em um tubo forçando o sistema operacional a enviar os dados agora.
No seu caso, adicionando proc.stdin.flush()
no loop principal principal e um sys.stdout.flush()
no loop de criança após a impressão deve corrigir seu problema.
Você também deve considerar mover o código que lê do outro processo para um thread. A idéia aqui é que você nunca pode saber quando os dados chegarão e o uso de um thread ajuda a entender esses problemas enquanto escreva o código que processa os resultados.
Neste lugar, eu queria mostrar a nova documentação do Python 2.6, mas também não explica o problema de descarga :( oh bem ...