2009-06-08 9 views
16

J'essaie de lire les lignes d'un tuyau et de les traiter, mais je fais quelque chose de stupide et je ne peux pas comprendre quoi. Le producteur va garder indéfiniment, comme la production de lignes ceci:Python - lignes de lecture simples à partir d'un tuyau

producer.py

import time 

while True: 
    print 'Data' 
    time.sleep(1) 

Le consommateur a juste besoin de vérifier les lignes périodiquement:

consumer.py

import sys, time 
while True: 
    line = sys.stdin.readline() 
    if line: 
     print 'Got data:', line 
    else: 
     time.sleep(1) 

Lorsque je lance ce dans le shell Windows comme python producer.py | python consumer.py, il dort juste pour toujours (ne semble jamais obtenir des données?) Il semble que le problème est peut-être que le prod L'ucer ne se termine jamais, car si j'envoie une quantité finie de données, alors cela fonctionne bien.

Comment puis-je recevoir les données et les présenter au consommateur? Dans la vraie application, le producteur est un programme C++ sur lequel je n'ai aucun contrôle.

Répondre

16

Certaines anciennes versions de Windows simulaient des tubes à travers des fichiers (donc ils étaient sujets à de tels problèmes), mais cela n'a pas posé de problème depuis plus de 10 ans. Essayez d'ajouter un

sys.stdout.flush() 

au producteur après la print, et aussi essayer de faire le stdout du producteur unbuffered (en utilisant python -u).

Bien sûr, cela n'aide pas si vous n'avez aucun contrôle sur le producteur - s'il tamponne trop de sa sortie, vous allez encore attendre longtemps.

Malheureusement - alors qu'il existe de nombreuses approches pour résoudre ce problème sur les systèmes d'exploitation Unix, tels que pyexpect, pexpect, exscript et paramiko, je doute l'un d'eux fonctionne sous Windows; Si c'est effectivement le cas, j'essaierai Cygwin, qui met assez de placage de type Linux sur Windows pour permettre souvent l'utilisation d'approches de type Linux sur une machine Windows.

7

Il s'agit d'E/S bufferisées par défaut avec Python. Passez l'option -u à l'interpréteur pour désactiver ce comportement:

python -u producer.py | python consumer.py 

Il résout le problème pour moi.

+0

Avez-vous lu la dernière phrase de la question? – jwg