2011-03-25 6 views
3

J'ai un processus qui crée plusieurs sous-processus avec lesquels il doit être couplé dans Python 2.5. J'utilise le module de sous-processus pour démarrer les processus, en définissant stdin et stdout sur subprocess.PIPE. Jusqu'ici tout va bien.Protocole prédéfini pour la communication sur stdin/stdout/pipes en Python?

Dans une boucle, je lance ensuite select.select() sur le flux stdout de chaque sous-processus en attendant qu'ils me disent qu'ils sont prêts. J'écris ensuite à leur stdin pour leur donner du travail et répéter le processus. À l'heure actuelle, j'utilise simplement stdin.write et stdout.readline pour préformer la communication. Cependant, j'aimerais pouvoir communiquer des messages complexes entre les processus. Les messages terminés par un simple saut de ligne ne suffiront pas (à moins que je ne prenne des pas pour échapper d'une manière ou d'une autre aux nouvelles lignes dans les messages). Je pense que je peux préfixer tous les messages avec la longueur en octets afin que mes messages ressemblent à:

6:foobar 

Mais cela me amène à ma question: quelque chose comme cela existe déjà? Je ne veux pas vraiment réinventer la roue ici. Je veux une bibliothèque qui me dit quand un message complet est prêt et me le remet. Il y a beaucoup d'autres protocoles qui font des choses comme ça de différentes manières (TCP, Serveurs de Message Queue, HTTP, etc.) mais ils sont tous trop lourds pour mon cas d'utilisation. Quelle est la bonne façon de faire passer le message entre les processus en Python?

Répondre

1

Vous pouvez utiliser json ou pickle pour coder la structure de données qui contient le message, puis l'utiliser de l'autre côté pour lire le message.

+0

Bien sûr, mais je dois toujours m'inquiéter de l'échappement ou d'une autre manière de définir les limites du message, non? (Peut-être que JSON échappe aux nouvelles lignes, je ne suis pas sûr de Pickle.) Je veux aussi m'assurer que, si le message arrive en morceaux, en raison de la mise en mémoire tampon, je ne manque rien. –

+0

Si les messages ne sont pas trop volumineux et ne viennent pas trop vite, je ne vois pas de problème à laisser 'select' le gérer. Si vous trouvez un problème avec le taux de message, vous pouvez vouloir regarder un analyseur progressif qui peut être capable de gérer les messages concaténés. –

+0

Un coup d'oeil sur cPickle me montre qu'il met de nouvelles lignes dans ses chaînes, ce qui signifie qu'il est hors de la table par lui-même: >>> print pickle.dumps ("a \ nb") S'a \ nb ' p1 . –

1

Il existe des frameworks qui vous aident vraiment à traiter ce type de fonctionnalités. Si vous souhaitez envoyer des messages plus complexes sans vous soucier des problèmes de synchronisation. Voici quelques exemples de cadres sont très bons:

Ces cadres, la plupart du temps, le travail sur le dessus de TCP/IP. Une approche légèrement différente de vos trucs. Mais, peut-être quelque chose que vous devriez considérer.

Questions connexes