Vor (langer) Zeit habe ich einen Web-Spider geschrieben, den ich multithreaded habe, damit gleichzeitig Anfragen auftreten können. Das war in meiner Python-Jugend, in den Tagen, bevor ich über die GIL und die damit verbundenen Probleme für Multithread-Code Bescheid wusste (IE, die meisten Dinge werden nur serialisiert!) ...
Ich möchte diesen Code überarbeiten, um ihn robuster und leistungsfähiger zu machen. Grundsätzlich gibt es zwei Möglichkeiten, dies zu tun: Ich könnte das neue Multiprocessing-Modul in 2.6+ verwenden oder mich für ein reaktor- / ereignisbasiertes Modell entscheiden. Ich würde das lieber später machen, da es viel einfacher und weniger fehleranfällig ist.
Die Frage bezieht sich also darauf, welcher Rahmen am besten zu meinen Bedürfnissen passt. Das Folgende ist eine Liste der Optionen, die ich bisher kenne:
- Twisted : Der Urvater der Python-Reaktor-Frameworks: scheint jedoch komplex und etwas aufgebläht zu sein. Steile Lernkurve für eine kleine Aufgabe.
- Eventlet : Von den Jungs von Lindenlab . Greenlet-basiertes Framework, das auf diese Art von Aufgaben ausgerichtet ist. Ich habe mir den Code angesehen und er ist nicht allzu hübsch: Nicht pep8-konform, mit Drucken übersät (warum machen die Leute das in einem Framework!?), Scheint die API ein wenig inkonsistent zu sein.
- PyEv : Unreif , scheint momentan niemand zu sein, der es benutzt, obwohl es auf libevent basiert, also hat es ein solides Backend.
- asyncore : Aus der stdlib: über low-level, scheint eine Menge Beinarbeit zu sein, nur um etwas in Gang zu bringen.
- tornado : Obwohl dies ein serverorientiertes Produkt ist, das für die Serverung dynamischer Websites entwickelt wurde, verfügt es über einen asynchronen HTTP-Client und einen einfachen ioloop . Sieht so aus, als könnte es die Arbeit erledigen, aber nicht das, wofür es gedacht war. [edit: läuft leider nicht unter Windows, was für mich zählt - es ist eine Voraussetzung für mich, diese lahme Plattform zu unterstützen]
Gibt es etwas, das ich überhaupt vermisst habe? Sicherlich muss es da draußen eine Bibliothek geben, die zum Sweet Spot einer vereinfachten asynchronen Netzwerkbibliothek passt!
[edit: Vielen Dank an intgr für seinen Zeiger auf diese Seite . Wenn Sie nach unten scrollen, werden Sie sehen, dass es eine wirklich schöne Liste von Projekten gibt, die darauf abzielen, diese Aufgabe auf die eine oder andere Weise anzugehen. Es scheint tatsächlich, dass sich die Dinge seit der Einführung von Twisted tatsächlich weiterentwickelt haben: Die Menschen scheinen nun eine auf Co-Routine basierende Lösung gegenüber einer herkömmlichen reaktor- / rückruforientierten Lösung zu bevorzugen . Die Vorteile dieses Ansatzes sind klarer, direkterer Code: Ich habe ihn sicherlich in der Vergangenheit gefunden, insbesondere bei der Arbeit mit boost.asioIn C ++ kann dieser auf Rückrufen basierende Code zu Designs führen, die schwer zu verfolgen sind und für das ungeübte Auge relativ dunkel sind. Durch die Verwendung von Co-Routinen können Sie Code schreiben, der zumindest etwas synchroner aussieht. Ich denke, jetzt ist es meine Aufgabe, herauszufinden, welche dieser vielen Bibliotheken mir gefällt, und es auszuprobieren! Ich bin froh, dass ich jetzt gefragt habe ...]
[Bearbeiten: Vielleicht von Interesse für jeden, der diese Frage verfolgt oder über sie gestolpert ist oder sich in irgendeiner Weise um dieses Thema kümmert: Ich habe eine wirklich gute Zusammenfassung des aktuellen Status der verfügbaren Tools für diesen Job gefunden]
select
für das E / A-Multiplexing verwendet wird. Aber Sie sollten in der Lage sein, mit Tornado-Pyuv eine anständige Leistung zu erzielen . 2. In Python 3.3+ und seinem Backport- Trollius gibt es jetzt Asyncio , mit dem jede Tornado-Anwendung in ihrer Ereignisschleife ausgeführt werden kann (Twisted wird bald unterstützt).