Domanda

Sto riscontrando problemi nel reindirizzare lo stdio di un altro programma usando il modulo di sottoprocesso. Basta leggere da stdout per appendere e Popen.communicate () funziona ma chiude i tubi dopo aver letto / scritto. Qual è il modo più semplice per implementarlo?

Stavo giocando con questo su 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
È stato utile?

Soluzione

Non si adatta al 100% al tuo esempio ma aiuta a comprendere il problema di fondo: il processo P avvia il figlio C. Il figlio C scrive qualcosa nel suo stdout. stdout di C è una pipe che ha un buffer di 4096 caratteri e l'output è più breve di quello. Ora, C attende alcuni input. Per C, va tutto bene.

P attende l'output che non arriverà mai perché il sistema operativo non vede alcun motivo per svuotare il buffer di output di C (con così pochi dati al suo interno). Poiché P non ottiene mai l'output di C, non scriverà mai nulla su C, quindi C si blocca in attesa dell'input da P.

Correzione: utilizzare flush dopo ogni scrittura su una pipe costringendo il sistema operativo a inviare i dati ora .

Nel tuo caso, aggiungendo proc.stdin.flush () nel ciclo while principale e un sys.stdout.flush () nel ciclo figlio dopo la stampa dovrebbe risolvere il tuo problema.

Dovresti anche considerare di spostare il codice che legge dall'altro processo in un thread. L'idea qui è che non puoi mai sapere quando arriveranno i dati e l'utilizzo di un thread ti aiuta a capire questi problemi mentre scrivi il codice che elabora i risultati.

In questo posto, volevo mostrarti la nuova documentazione di Python 2.6 ma non spiega nemmeno il problema del flush :( Oh beh ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top