2010-08-02 14 views
11

sto creando un processo da Win32 usando CreateProcess, impostando le hStdOutput e hStdError proprietà di STARTUPINFO convogliare maniglie creato con CreatePipe. Ho due thread che leggono le pipe, in attesa che i dati diventino disponibili (o il processo da completare, a quel punto controlla che non ci siano dati mancanti prima di terminare il thread).
Quando i dati diventano disponibili, scrivo l'output in modo efficace in una grande casella di testo.buffer Disable su reindirizzati stdout tubo (API Win32, C++)

Quello che sta succedendo è che l'output è in fase di buffering, quindi un processo lento in esecuzione ottiene solo blocchi di dati lanciati nella casella di testo, ma non "come accade".

Non sono sicuro che sia il pipe che sta eseguendo il buffering, o qualcosa a che fare con il reindirizzamento.

Esiste un modo per impostare il pipe su unbuffered o avviare il processo in modo tale che lo stdout venga inviato il prima possibile?

sto testando con un'applicazione di test che stampa le linee uno secondo a parte

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

Si trasmette senza problemi quando il processo sta scrivendo su una console? Su Linux questo è un problema abbastanza noto, e la soluzione è allocare uno pseudo-tty perché alcuni programmi attivano il buffering quando l'output non è un tty. Su Windows non è comune controllare il tipo di file di stdout, quindi non mi aspetto che il buffering diventi diverso in una pipe vs in una console. –

+0

Sì, quando è sulla console (ad esempio cmd.exe), lo streaming come previsto, con i ritardi e così via. –

+0

Come si scrive il processo sullo standard output? Penso che potresti aver attivato il buffering degli stream C o C++. – wilx

risposta

4

Il buffer è probabilmente nel runtime C (printf, ecc) e non c'è molto che si può fare su di esso (IIRC si fa un isatty() controlla per determinare una strategia di buffering)

+0

Questa sarebbe la risposta in POSIX. Ma Windows non ha alcun concetto di tty, né alcuna funzione 'isatty'. –

+1

@Ben Voigt: il runtime MS c ha ancora: http://msdn.microsoft.com/en-us/library/f4s0ddew%28v=VS.80%29.aspx – Anders

+0

scuotere la testa con stupore presso ".NET. "Equivalente Framework", nessuno dei quali è equivalente in alcun modo –

0

C'è SetNamedPipeHandleState, ma controlla solo il buffering per tubi a distanza, non quando entrambe le estremità sono sullo stesso computer.

+0

Sì, l'ho visto, ma, come dici tu, non cambia nulla quando entrambe le estremità si trovano sullo stesso computer –

0

Mi sembra che si può risolvere il problema se si imposta il hStdOutput e hStdError di STARTUPINFOnon a tubo maniglie creati con CreatePipe, ma invece di creare una named pipe (con CallNamedPipe funzione esattamente come si è utilizzato se prima utilizzando anche SECURITY_ATTRIBUTES con bInheritHandle = TRUE, vedere http://msdn.microsoft.com/en-us/library/aa365782.aspx) e quindi aprirlo per nome in relazione a CreateFile utilizzando il flag FILE_FLAG_WRITE_THROUGH. Come si può leggere sul MSDN (http://msdn.microsoft.com/en-us/library/aa365592.aspx):

Il client pipa possono utilizzare CreateFile per abilitare la modalità sovrapposta specificando FILE_FLAG_OVERLAPPED o per abilitare modalità write-through specificando FILE_FLAG_WRITE_THROUGH.

Quindi, solo riaprire il tubo con rispetto della CreateFile utilizzando FILE_FLAG_WRITE_THROUGH bandiera e impostare la maniglia/maniglie per hStdOutput e hStdError di STARTUPINFO.

+1

FILE_FLAG_WRITE_THROUGH 0x80000000 La modalità Write-through è abilitata. Questa modalità influenza solo le operazioni di scrittura su pipe di tipo byte e, quindi, ** solo quando i processi client e server si trovano su computer diversi. ** Se questa modalità è abilitata, le funzioni che scrivono su una named pipe non vengono restituite fino a quando i dati non vengono scritti viene trasmesso attraverso la rete e si trova nel buffer della pipe sul computer remoto. Se questa modalità non è abilitata, il sistema migliora l'efficienza delle operazioni di rete mediante il buffering dei dati fino a quando si accumula un numero minimo di byte o fino a quando non trascorre un tempo massimo. –