Un propre, alternative légère à Python tordu?
Un (long) tout à l'heure, j'ai écrit une web-araignée que je multithread pour permettre à des demandes concurrentes pour se produire en même temps. Qui était dans mon Python de la jeunesse, dans les jours avant que je savais à propos de la GIL et les malheurs qu'il crée pour le code multithread (c'est à dire, la plupart du temps des trucs se termine juste en haut sérialisé!)...
J'aimerais retravailler ce code pour le rendre plus robuste et plus performant. Il existe essentiellement deux façons que je pouvais le faire: j'ai pu utiliser le nouveau module multiprocessing en 2.6+ ou je pourrais aller pour un réacteur /événement basée sur le modèle d'une certaine sorte. Je préfère faire le plus tard, car il est beaucoup plus simple et moins sujettes à l'erreur.
De sorte que la question se rapporte à ce qui cadre le mieux adapté à mes besoins. Ce qui suit est une liste des options que je sais à propos de la mesure:
- Twisted: L'ancêtre de Python réacteur cadres: semble complexe et un peu gonflé cependant. Courbe d'apprentissage abrupte pour un petit groupe.
- Eventlet: Les gars à lindenlab. Greenlet basé cadre qui est orienté vers ces types de tâches. J'ai eu un coup d'oeil au code et si c'est pas trop jolie: non-pep8 conforme, dispersés avec des impressions (pourquoi des gens font cela dans un cadre!?), API semble un peu incohérent.
- PyEv: Immature, ne semble pas être n'importe qui à l'utiliser maintenant, bien qu'il soit basé sur libevent il y a donc un solide arrière-plan.
- asyncore: À partir de la stdlib: über faible niveau de, ressemble à beaucoup de travail sur le terrain impliqués juste pour obtenir quelque chose sur le sol.
- tornade: Si c'est un serveur orienté produit conçu pour le serveur de sites web dynamiques, il ne disposent d'un async client HTTP et un simple ioloop. Regarde comme elle pourrait faire le travail, mais pas de quoi il était destiné.
[edit: ne fonctionne pas sur Windows, malheureusement, qui compte pour moi - c'est une exigence pour moi, à l'appui de cette lame plate-forme]
Est là tout ce que j'ai manqué à tous? Il doit sûrement y avoir une bibliothèque qui s'adapte le sweet-spot d'une simplification de la async mise en réseau de la bibliothèque!
[edit: un grand merci à intgr pour son pointeur à cette page. Si vous faites défiler vers le bas, vous verrez il y a vraiment une belle liste de projets qui visent à s'attaquer à cette tâche d'une manière ou d'une autre. Il semble effectivement que les choses ont bien évolué depuis la création de Twisted: maintenant les gens semblent favoriser une co-routine en fonction de la solution plutôt qu'une traditionnelle réacteur /rappel orientée. Les avantages de cette approche sont plus claire, plus directe, code: j'ai certainement trouvé dans le passé, surtout lorsque l'on travaille avec coup de pouce.asio en C++, qui de rappel en fonction du code peut conduire à des conceptions qui peut être difficile à suivre et sont relativement obscure pour un oeil non averti. À l'aide de co-routines permet d'écrire du code qui ressemble un peu plus synchrone au moins. Je suppose que maintenant, ma tâche est de travailler sur l'une de ces nombreuses bibliothèques, j'aime bien le look et lui donner un aller! Heureux j'ai demandé aujourd'hui...]
[edit: peut-être d'intérêt pour tous ceux qui ont suivi ou trébuché sur cette question ou un soucis sur ce sujet dans tous les sens: j'ai trouvé une très bonne description de l'état actuel de les outils disponibles pour ce travail]
- Python est multithread, il n'a tout simplement pas permettre à deux threads pour exécuter du code Python en même temps.
- en effet, il est, donc, en théorie, puisque
socket
est un module C, si ils laissent le GIL aller de l'avant d'appeler le sous-jacent de routine, les choses pourraient en fait être simultanées. Même encore, je crois que j'ai envie de revenir à quelque chose de single-threaded. - J'ai appris beaucoup plus de votre question que de réponses.
- hé, merci, je suppose! Il y a eu quelques bons pointeurs dans les réponses aussi, spécifiquement intgr de. Je connaissais beaucoup d'options là-bas et je ne voulais pas les réponses emballés avec ceux-ci donc, j'ai pensé aller à la peine de mentionner ce que je savais 🙂
- > maintenant les gens semblent favoriser une co-routine en fonction de la solution plutôt qu'une traditionnelle réacteur / rappel orienté Ce n'est pas une bonne comparaison. "co-routine basée sur des solutions" et "réacteur" orientées vers les solutions sont orthogonaux. (En ignorant le fait que Python n'a pas de coroutines) jetez un oeil à Tordu de inlineCallbacks pour voir comment vous pouvez avoir le style de programmation vous semblent préférer grâce à une solide maturité de la couche réseau qui ne va pas vous exposer à des complexes plate-forme de particularités.
- Calderone: OK, je vais regarder inlineCallbacks, qui sont nouveaux pour moi. Comme je l'ai dit avant, il y a une courbe d'apprentissage abrupte avec tordus, où dois-je commencer pour le genre de petite tâche que je veux réaliser? De toute façon, je suppose que pourquoi certaines personnes voient les co-routines comme une bonne alternative est résumée ici: en apesanteur.io/arrière-plan mais vous avez raison: je suis sûr que l'un quelconque des co-routine implémentations de Python peut être utilisé avec des Tordus dans la théorie. Et oui, Python n'est pas co-routines hors de la boîte, mais vous pouvez ajouter assez facilement.
- Calderone: Vous pouvez mettre en œuvre des coroutines dans la plaine de Python en utilisant le générateur de fonctions (oui c'est un hack, mais ils sont toujours coroutines).
- Je ne comprends pas Tordu. Il semble vouloir mettre en œuvre chaque protocole dans le monde, oh oui, et veut travailler avec n'importe quel événement de la boucle dans le monde sans que l'utilisateur configuration (GTK, etc). Cela aurait été bien si il y avait quelque chose asynchrone qui permet simplement vous pile de protocoles toutefois vous le souhaitez.
- Twisted est quelque chose asynchrone qui permet simplement vous pile de protocoles toutefois vous voulez :). J'ai donné une conférence sur, entre autres choses, comment léger, il est. Voir ici pycon.tv/#/video/58
- Une chance pour une mise à jour de cette question et/ou des réponses à refléter l'état actuel de l'art?
- Quelques points à ajouter: 1. Tornade fonctionne très bien sur Windows. C'est juste pas aussi performant et évolutif, car il utilise
select
pour les I/O de multiplexage. Mais vous devriez être en mesure d'obtenir un rendement décent avec tornade-pyuv. 2. Il est maintenant asyncio en Python 3.3,+ et de ses backport trollius qui permet d'exécuter n'importe quel Tornade application dans sa boucle d'événement (Twisted sera bientôt pris en charge).
Vous devez vous connecter pour publier un commentaire.
J'ai aimé le accord module Python qui s'appuie sur Stackless Python microthreads ou Greenlets pour la lumière-poids de filetage. Tout blocage du réseau I/O est de façon transparente en asynchrone via un seul
libevent
boucle, de sorte qu'il devrait être presque aussi performant qu'un vrai serveur asynchrones.Je suppose que c'est similaire à Eventlet de cette façon.
L'inconvénient est que son API est assez différente de Python
sockets
/threading
modules; vous avez besoin de réécrire un peu juste de votre demande (ou d'écrire une compatibilité cale d'épaisseur de couche)Edit: Il semble qu'il y a aussi cogen, ce qui est similaire, mais utilise Python 2.5 est amélioré générateurs pour son coroutines, au lieu de Greenlets. Cela rend plus facile à transporter que l'accord et d'autres solutions de rechange. Réseau d'e/S est fait directement avec epoll/kqueue/iocp.
Tordu est complexe, vous avez raison à ce sujet. Twisted est pas de ballonnement.
Si vous prenez un coup d'oeil ici: http://twistedmatrix.com/trac/browser/trunk/twisted vous trouverez un ensemble organisé, complet, et très bien testé suite de de nombreux protocoles de l'internet, ainsi comme l'aide de code à écrire et à déployer très sophistiqué applications réseau. Je ne confondez pas les gonfler avec exhaustivité.
C'est bien connu, ce qui est Tordu la documentation n'est pas le plus convivial du premier coup d'œil, et je crois qu'il se détourne d'un regrettable nombre de personnes. Mais Tordu est incroyable (à mon humble avis), si vous mettez dans le temps. Je l'ai fait et il s'est avéré être la peine, et je le recommande à d'autres d'essayer la même chose.
gevent est eventlet nettoyé.
API-sage, il suit les mêmes conventions que la bibliothèque standard (en particulier, le filetage et le multitraitement modules) où il fait sens. Si vous avez des choses familières comme La file d'attente et L'événement de travailler avec.
Il ne supporte libevent (mise à jour: libev depuis la 1.0) en tant que réacteur de mise en œuvre, mais l'exploite à fond, avec un rapide WSGI serveur basé sur libevent-http et la résolution des requêtes DNS par le biais de libevent-dns plutôt que d'utiliser un pool de threads comme la plupart des autres bibliothèques. (mise à jour: depuis 1.0 c-ares sert à faire asynchrone des requêtes DNS; pool de threads est également une option.)
Comme eventlet, il fait les rappels et Deferreds inutiles en utilisant greenlets.
Découvrez les exemples: téléchargement simultané de plusieurs url, le temps d'interrogation webchat.
Vraiment comparaison intéressante de ces cadres a été réalisé par Nicolas Piël sur son blog: c'est bien intéressant à lire!
Aucune de ces solutions permettront d'éviter le fait que le GIL empêche CPU parallélisme - ils sont simplement meilleurs moyens d'obtenir des IO parallélisme que vous avez déjà avec les threads. Si vous pensez que vous pouvez faire mieux IO, par tous les moyens de poursuivre l'un de ces, mais si votre goulet d'étranglement dans le traitement des résultats de rien, ici, aidera sauf pour le module multiprocessing.
Je n'irais pas jusqu'à qualifier Tordu de ballonnement, mais il est difficile pour envelopper votre tête autour de. J'ai évité vraiment de décantation dans un apprendre pour un bon moment comme je l'ai toujours voulu quelque chose d'un peu plus facile pour les "petites tâches".
Cependant, maintenant que j'ai travaillé avec elle, je dois dire avoir toutes les batteries inclus est TRÈS agréable.
Tous les autres async bibliothèques, j'ai travaillé avec des cours de façon moins mature qu'elles apparaissent même. Tordu de la boucle d'événement est solide.
Je ne suis pas tout à fait sûr de savoir comment résoudre le raide Tordu courbe d'apprentissage. Cela pourrait aider si quelqu'un aurait une fourche et nettoyer un peu les choses, comme le retrait de toutes les rétro compatibilité avec les fichiers inutiles et les morts projets. Mais c'est la nature de la maturité des logiciels, je suppose.
PortableGtkReactor
?Kamaelia n'a pas encore été mentionnés. Sa simultanéité modèle est basé sur le câblage de l'ensemble des composants avec la transmission de messages entre les boîtes et des boîtes d'envoi. Ici's un bref aperçu.
J'ai commencé à utiliser des tordus pour certaines choses. La beauté de elle est presque parce que c'est "gonflée". Il y a des connecteurs pour à peu près tous les principaux protocoles de là-bas. Vous pouvez avoir un bot jabber qui va prendre les commandes et de la poste à un serveur irc, e-mail à quelqu'un, l'exécution de la commande, lire à partir d'un serveur NNTP, et de surveiller une page web pour des changements. La mauvaise nouvelle, c'est qu'il peut faire tout cela, et peut rendre les choses trop complexes pour des tâches simples comme l'OP expliqué. L'avantage de python est bien de vous inclure uniquement ce dont vous avez besoin. Ainsi, alors que le téléchargement peut être de 20 mo, vous pouvez inclure seulement de 2 mo de bibliothèques (ce qui est encore beaucoup). Ma plus grande plainte avec twisted est bien qu'ils incluent des exemples, rien au-delà d'un simple serveur tcp vous êtes sur votre propre.
Alors que pas un python solution, je l'ai vu node.js le gain de beaucoup plus de traction que de la fin. En fait j'ai réfléchi à la recherche pour les projets plus petits, mais je viens de grincer des dents quand j'entends javascript 🙂
Il y a un bon livre sur le sujet: "Tordu Réseau éléments essentiels de la Programmation", par Abe Fettig. Les exemples montrent comment écrire très Pythonic code, et pour moi, personnellement, ne pas me frapper sur la base d'une pléthorique cadre. Regardons les solutions dans le livre, si elles ne sont pas propre, alors je ne sais pas ce qu'propres moyens.
Ma seule énigme est la même que j'ai avec d'autres cadres, comme le Rubis. Je m'inquiète, est-il à l'échelle vers le haut? Je ne voudrais pas commettre d'un client à un cadre qui va avoir des problèmes d'évolutivité.
Essoreuse est un petit asynchrone socket cadre qui utilise pyev. Ses très rapide, principalement en raison de pyev. Il tente de fournir une interface similaire comme torsadée avec quelques légères modifications.
Aussi essayer Syncless. C'est coroutine base (donc c'est similaire à la Concurrence, Eventlet et gevent). Il met en œuvre drop-in non-blocage de remplacement pour support.socket, socket.gethostbyname (etc.), le protocole ssl.SSLSocket, temps.le sommeil et la sélectionner.sélectionnez. C'est rapide. Il doit Stackless Python et libevent. Il contient obligatoirement une extension Python écrit en C (Pyrex/Cython).
Je confirme la bonté de syncless. Il peut utiliser libev (le plus récent, plus propre et une meilleure performance de la version de libevent). Il y a quelques temps, il n'a pas autant de soutien libevent a, mais maintenant, le processus d'élaboration d'aller plus loin et est très utile.
Si vous voulez juste un Simplifiée, léger Requête HTTP de la Bibliothèque puis-je trouver Unirest vraiment bon
Vous êtes les bienvenus pour regarder PyWorks, qui prend une approche assez différente. Il permet à des instances d'objet à exécuter dans leur propre sujet et fait appel de la fonction de l'objet asynchrone.
Simplement laisser une classe hérite de la Tâche à la place de l'objet et il est asynchrone, tous les appels de méthodes sont des Proxys. Les valeurs de retour (si vous en avez besoin) sont des Futurs mandataires.
PyWorks peut être trouvé sur http://bitbucket.org/raindog/pyworks