2012-01-27 13 views
5

tengo un programa de servidor de larga ejecución (por ejemplo, el programa A) que está escrito en QT/C++. el programa no es tan estable, así que decido escribir un script de python para reiniciarlo si falla. el problema es que el programa puede comenzar a fallar (si le di un puerto en uso), imprimir el error y luego simplemente colgar allí sin salir, por lo que debo monitorear el stdout del programa y matarlo en el arranque fallido.programa de la consola de Windows stdout se almacena en búfer al usar la redirección de tuberías

esto es una parte de mi código final (bueno, de hecho, esto está bien, puede ignorarlo):

self.subp = subprocess.Popen(
    r'.\A.exe -server %d' % portnum, 
    stdout=subprocess.PIPE, bufsize=1) 
for line in iter(self.subp.stdout.readline, ''): 
    print(line, end='') 

pero me encontré con que no puedo leer nada de la salida estándar de sub-proceso, el readline el método simplemente está bloqueando allí, y si elimino el proceso A, el script de python simplemente sale sin ningún resultado. al principio, pensé que era un problema de módulo de subproceso, pero después de algunas pruebas descubrí que no. si reemplazo la línea de comandos de A.exe con algún otro programa de la consola de Windows, ping -t, por ejemplo, todo funciona correctamente. así que pensé que podría ser el problema del programa A.

suerte, tengo el código fuente de A, aquí es una pieza que trata con la salida:

printf("Server is starting on port %u\n", Config.ServerPort); 

if(server->listen()) 
    printf("Starting successfully\n"); 
else 
    printf("Starting failed!\n"); 

buscándole agrego fflush(stdout); al final de esta pieza de código, reconstruir el programa, y ​​ahora funciona

así que mi problema es que aún no puedo entender, ¿qué hay de malo con el código original del programa A? sin descarga forzada, puede imprimir correctamente esas cadenas en una consola de Windows, inmediatamente después de que el programa comenzó. ¿por qué la salida está almacenada en búfer cuando se usa tubería en su salida? He leído que en el implemento c estándar, la salida se vaciará automáticamente en la línea nueva, pero ¿por qué no en mi situación? ¿Es esto un problema de Windows o compilador?

el programa A se compila con QT/C++, la versión QT es 4.7.4 (x32), el compilador C++ es ming32 g ++ viene con QT (GCC 4.4.0), todas las pruebas se realizaron en la plataforma win7x64, y mi versión de Python es 2.7.2

Respuesta

1

Me encontré con la misma pregunta que la suya. (How fo force subprocess to refresh stdout buffer?)

la salida estándar de la tubería redirigir en las ventanas de memoria intermedia totalmente defaultly, significa que usted no puede leer nada de tubería a menos que el subproceso de ejecución para finalizar o invocar fflush después de printf en el subproceso.

Esto no es un problema de Windows, pero por diseño, y es como un problema a veces.

Y no he encontrado una buena solución para esta pregunta, dime si la resuelves.

+0

Creo que el [enlace relacionado] (http://stackoverflow.com/q/20503671/4279) en los comentarios en su enlace explica mucho, gracias – adamhj

Cuestiones relacionadas