2010-08-02 10 views
11

estoy lanzando un proceso de Win32 usando CreateProcess, el establecimiento de los hStdOutput y hStdError propiedades de STARTUPINFO a la tubería maneja crea con CreatePipe. Tengo dos hilos que leen los tubos, esperando que los datos estén disponibles (o el proceso para completar, en cuyo punto comprueba que no quedan datos antes de terminar el hilo).
A medida que los datos están disponibles, escribo el resultado de manera efectiva en un gran cuadro de texto.búfer Deshabilitar a un redirigir la salida estándar de tubo (API Win32, C++)

Lo que está sucediendo es que la salida se está almacenando en el búfer, por lo que un proceso lento simplemente genera fragmentos de datos en el cuadro de texto, pero no "como sucede".

No estoy seguro de si es la tubería que está haciendo el almacenamiento en búfer, o algo que ver con la redirección.

¿Hay alguna forma de configurar la tubería para ser sin buffer, o iniciar el proceso de tal manera que la stdout se envíe lo antes posible?

estoy probando con una aplicación de prueba que se imprime líneas intervalos de un segundo

Here is line one 
(waits one second) 
Here is line two 
(waits one second) 
... etc 
+0

¿Transmite sin problemas cuando el proceso está escribiendo en una consola? En Linux este es un problema bastante conocido, y la solución es asignar un pseudo-tty porque algunos programas activan el almacenamiento en búfer cuando el resultado no es un tty. En Windows, no es común comprobar el tipo de archivo de stdout, por lo que no esperaría que el almacenamiento en búfer fuera diferente en una tubería frente a una consola. –

+0

Sí, cuando está en la consola (es decir, cmd.exe), se transmite como se esperaba, con los retrasos, etc. –

+0

¿Cómo está escribiendo el proceso en la salida estándar? Creo que podría estar activando el almacenamiento en búfer de secuencias C o C++. – wilx

Respuesta

4

El búfer está probablemente en el tiempo de ejecución C (printf, etc.) y no hay mucho que se pueda hacer al respecto (IIRC lo hace un isatty() una comprobación para determinar una estrategia de amortiguación)

+0

Esa sería la respuesta en POSIX. Pero Windows no tiene el concepto de una función tty ni de 'isatty'. –

+1

@Ben Voigt: el tiempo de ejecución de MS c todavía lo tiene: http://msdn.microsoft.com/en-us/library/f4s0ddew%28v=VS.80%29.aspx – Anders

+0

sacudiendo la cabeza con asombro en el ".NET Equivalente de Framework ", ninguna de las cuales es equivalente de ninguna manera –

0

Hay SetNamedPipeHandleState, pero sólo controla el almacenamiento en búfer para tuberías remotas, no cuando ambos extremos están en el mismo equipo.

+0

Sí, he visto eso, pero, como dices, no cambia nada cuando ambos extremos están en la misma computadora –

0

Me parece que puede resolver el problema si se establece la hStdOutput y hStdError de STARTUPINFOno a la tubería mangos creados con CreatePipe, pero en vez de que cree una canalizaciones con nombre (con CallNamedPipe funcionan exactamente como antes, si antes también usando SECURITY_ATTRIBUTES con bInheritHandle = TRUE, ver http://msdn.microsoft.com/en-us/library/aa365782.aspx) y luego abrir allí por su nombre con respecto a CreateFile usando la bandera FILE_FLAG_WRITE_THROUGH. Como se puede leer en el MSDN (http://msdn.microsoft.com/en-us/library/aa365592.aspx):

El cliente puede usar tubería CreateFile para habilitar el modo solapado especificando FILE_FLAG_OVERLAPPED o para permitir modo de escritura a través especificando FILE_FLAG_WRITE_THROUGH.

Así que vuelve a abrir el tubo con respecto a CreateFile usando FILE_FLAG_WRITE_THROUGH bandera y ajuste el mango/maneja a hStdOutput y hStdError de STARTUPINFO.

+1

FILE_FLAG_WRITE_THROUGH 0x80000000 El modo de escritura está habilitado. Este modo solo afecta a las operaciones de escritura en los conductos de bytes y, a continuación, ** solo cuando los procesos del cliente y del servidor se encuentran en computadoras diferentes. ** Si este modo está habilitado, las funciones que escriben en un conducto especificado no regresan hasta que se escriben los datos se transmite a través de la red y está en el búfer de la tubería en la computadora remota. Si este modo no está habilitado, el sistema mejora la eficiencia de las operaciones de red almacenando en el búfer datos hasta que se acumule un número mínimo de bytes o hasta que transcurra un tiempo máximo. –

Cuestiones relacionadas