2010-08-02 19 views
11

Je fraye un processus de Win32 en utilisant CreateProcess, fixant les hStdOutput et hStdError propriétés de STARTUPINFO à tuyau poignées créé avec CreatePipe. J'ai deux threads lisant les tuyaux, attendant que les données deviennent disponibles (ou le processus à compléter, à quel point il vérifie qu'il n'y a plus de données avant de terminer le thread).
Au fur et à mesure que les données deviennent disponibles, j'écris la sortie sur une grande zone de texte.tampon Disable sur le tuyau de sortie standard redirigé (API Win32, C++)

Ce qui se passe est que la sortie est mise en mémoire tampon, donc un processus lent exécute seulement des blocs de données lancés dans la zone de texte, mais pas "comme cela arrive".

Je ne suis pas sûr si c'est le tuyau qui fait la mise en mémoire tampon, ou quelque chose à voir avec la redirection.

Y a-t-il un moyen de configurer le canal pour qu'il ne soit pas saturé ou de démarrer le processus de sorte que la sortie stdout soit envoyée le plus tôt possible?

Je teste avec une application de test qui imprime des lignes de une seconde

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

Le flux est-il fluide lorsque le processus écrit sur une console? Sur Linux c'est un problème assez connu, et la solution est d'allouer un pseudo-tty car certains programmes activent la mise en mémoire tampon quand la sortie n'est pas un tty. Sous Windows, il n'est pas courant de vérifier le type de fichier stdout, donc je ne m'attendrais pas à ce que la mise en mémoire tampon soit différente dans un tube par rapport à une console. –

+0

Oui, lorsqu'il est sur la console (c'est-à-dire cmd.exe), il est diffusé comme prévu, avec les retards et ainsi de suite. –

+0

Comment le processus écrit-il sur la sortie standard? Je pense que vous pourriez avoir activé la mise en mémoire tampon des flux C ou C++. – wilx

Répondre

4

La mise en mémoire tampon est probablement dans le runtime C (printf, etc.) et il n'y a pas grand-chose que vous pouvez faire à ce sujet (IIRC il fait un isatty() vérifier afin de déterminer une stratégie de mise en mémoire tampon)

+0

Ce serait la réponse dans POSIX. Mais Windows n'a pas de concept de tty, ni de fonction 'isatty'. –

+1

@Ben Voigt: le MS c runtime l'a toujours: http://msdn.microsoft.com/en-us/library/f4s0ddew%28v=VS.80%29.aspx – Anders

+0

secouant la tête avec étonnement à la ".NET Liste des équivalents-cadres ", dont aucun n'est équivalent de quelque façon que ce soit –

0

Il y a SetNamedPipeHandleState, mais il ne contrôle que mise en mémoire tampon pour les tuyaux à distance, et non lorsque les deux extrémités sont sur le même ordinateur.

+0

Oui, j'ai vu cela, mais, comme vous le dites, cela ne change rien lorsque les deux extrémités sont sur le même ordinateur –

0

Il me semble que vous peut résoudre le problème si vous définissez la hStdOutput et hStdError de STARTUPINFOpas au tuyau handles avec CreatePipe, mais au lieu de cela, vous créez un canaux nommés (avec CallNamedPipe fonctionnent exactement comme vous avez utilisé si, avant également d'utiliser SECURITY_ATTRIBUTES avec bInheritHandle = TRUE, voir http://msdn.microsoft.com/en-us/library/aa365782.aspx) et ensuite ouvrir par son nom à l'égard de CreateFile en utilisant le drapeau FILE_FLAG_WRITE_THROUGH. Comme vous pouvez le lire sur le MSDN (http://msdn.microsoft.com/en-us/library/aa365592.aspx):

Le client peut utiliser CreateFile tuyau pour activer le mode chevauchée en spécifiant FILE_FLAG_OVERLAPPED ou pour activer mode d'écriture en spécifiant par FILE_FLAG_WRITE_THROUGH.

donc réouvrir juste le tuyau par rapport à l'aide de CreateFileFILE_FLAG_WRITE_THROUGH drapeau et régler la poignée/poignées pour hStdOutput et hStdError de STARTUPINFO.

+1

FILE_FLAG_WRITE_THROUGH 0x80000000 Le mode d'écriture directe est activé. Ce mode n'affecte que les opérations d'écriture sur les canaux de type octet et, ensuite, ** uniquement lorsque les processus client et serveur sont sur des ordinateurs différents. ** Si ce mode est activé, les fonctions d'écriture dans un canal nommé ne sont pas retournées. est transmise sur le réseau et se trouve dans le tampon du tube sur l'ordinateur distant. Si ce mode n'est pas activé, le système améliore l'efficacité des opérations réseau en mettant en mémoire tampon les données jusqu'à ce qu'un nombre minimal d'octets s'accumule ou jusqu'à ce qu'un délai maximum se soit écoulé. –