2009-09-18 8 views
16

Tengo un programa que escribe en stdout y posiblemente en stderr. Quiero ejecutarlo desde python, capturando stdout y stderr. Mi código es el siguiente:¿Cómo puedo averiguar por qué el subproceso.Popen wait() espera para siempre si stdout = PIPE?

from subprocess import * 

p = Popen(exe, shell=TRUE, stdout=PIPE, stderr=PIPE) 
rtrncode = p.wait() 

Durante un par de programas, esto funciona bien, pero cuando he añadido una nueva, la nueva cuelga para siempre. Si elimino stdout=PIPE, el programa escribe su salida a la consola y termina y todo está bien. ¿Cómo puedo determinar qué está causando el bloqueo?

Usando python 2.5 en Windows XP. El programa no lee de stdin ni tiene ningún tipo de entrada de usuario (es decir, "presionar una tecla").

Respuesta

35

Cuando la memoria intermedia de una tubería se llena (normalmente 4 KB o más), el proceso de escritura se detiene hasta que un proceso de lectura haya leído algunos de los datos en cuestión; pero aquí no está leyendo nada hasta que se complete el subproceso, de ahí el punto muerto. The docs en wait decirlo muy claramente en verdad:

Advertencia Esto callejón sin salida si el proceso niño genera una salida suficiente a una tubería de salida estándar o stderr tal que lo bloquea en espera de la tubería OS búfer para aceptar más datos. Use communica() para evitar eso.

Si no puede utilizar communicate por alguna razón, tienen el subproceso de escritura en un archivo temporal, y luego se puede wait y leer ese archivo cuando esté listo - escribir en un archivo, en lugar de a una tubería , no se arriesga a un punto muerto

+0

Me ganaste un poco. +1 – MitMaro

+0

El archivo de ayuda instalado con Python 2.5 no tiene ese pequeño tidbit de información. Gracias –

+1

@Graeme, ah sí, los documentos de 2.6 están muy mejorados con los 2.5. –

1

Eche un vistazo al docs. Indica que no debe usar wait ya que puede causar un bloqueo muerto. Intenta usar communicate.

Cuestiones relacionadas