Cómo interactuar adecuadamente con un proceso utilizando un módulo de subproceso
-
22-07-2019 - |
Pregunta
Tengo problemas para redirigir stdio de otro programa usando el módulo de subproceso. Solo leer desde stdout da como resultado el bloqueo, y Popen.communicate () funciona pero cierra las tuberías después de leer / escribir. ¿Cuál es la forma más fácil de implementar esto?
Estaba jugando con esto en 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
Solución
No se ajusta al 100% a su ejemplo, pero ayuda a comprender el problema subyacente: el proceso P inicia al niño C. El niño C escribe algo en su stdout. stdout de C es una tubería que tiene un búfer de 4096 caracteres y la salida es más corta que eso. Ahora, C espera alguna entrada. Para C, todo está bien.
P espera la salida que nunca llegará porque el sistema operativo no ve ninguna razón para vaciar el búfer de salida de C (con tan pocos datos). Dado que P nunca obtiene la salida de C, nunca escribirá nada en C, por lo que C se cuelga esperando la entrada de P.
Solución: utilice el vaciado después de cada escritura en una tubería que obliga al sistema operativo a enviar los datos ahora .
En su caso, agregue proc.stdin.flush ()
en el ciclo while principal y un sys.stdout.flush ()
en el ciclo secundario después de la impresión debería solucionar su problema.
También debe considerar mover el código que lee del otro proceso a un hilo. La idea aquí es que nunca se puede saber cuándo llegarán los datos y usar un hilo le ayuda a comprender estos problemas mientras escribe el código que procesa los resultados.
En este lugar, quería mostrarle la nueva documentación de Python 2.6, pero tampoco explica el problema de descarga :( Oh, bueno ...