Como interagir adequadamente com um processo usando o módulo de subprocesso

StackOverflow https://stackoverflow.com/questions/443057

  •  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
Foi útil?

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 ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top