Ich habe vor kurzem an einem Haustier-Projekt in Python mit Kolben gearbeitet. Es ist ein einfacher Pastebin mit serverseitiger Syntax, der die Unterstützung mit Segmenten unterstützt. Da dies eine kostspielige Aufgabe ist, habe ich die Syntaxhervorhebung an eine Sellerie-Aufgabenwarteschlange delegiert, und im Anforderungshandler warte ich darauf, dass sie beendet wird. Unnötig zu sagen, dass dies lediglich die CPU-Nutzung für einen anderen Mitarbeiter verringert, da das Warten auf ein Ergebnis immer noch die Verbindung zum Webserver sperrt. Trotz meiner Instinkte, dass ich eine vorzeitige Optimierung wie die Pest vermeiden sollte, konnte ich mir immer noch nicht helfen, Asynchron zu betrachten.Python asynchrone und CPU-gebundene Aufgaben?
Async
Wenn haben in letzter Zeit Web-Entwicklung wurden folgende Python, Sie haben sicherlich gesehen, dass async überall. Was async ist, bringt kooperatives Multitasking zurück, was bedeutet, dass jeder "Thread" entscheidet, wann und wo er einem anderen nachgibt. Dieser nicht-präventive Prozess ist effizienter als OS-Threads, hat aber immer noch seine Nachteile. Im Augenblick scheint es 2 Hauptansätze zu sein:
- Ereignis/Rückruf style Multitasking
- Koroutinen
Die erste stellt concurrency durch lose gekoppelten Komponenten in einer Ereignisschleife ausgeführt. Obwohl dies in Bezug auf Race-Bedingungen sicherer ist und für mehr Konsistenz sorgt, ist es wesentlich weniger intuitiv und schwieriger zu programmieren als präemptives Multitasking.
Die andere ist eine eher traditionelle Lösung, näher am Programmiermodus mit Gewinde, wobei der Programmierer nur den Kontext manuell wechseln muss. Obwohl es anfälliger für Rennen und Deadlocks ist, bietet es eine einfache Drop-In-Lösung.
Die meisten asynchronen Arbeiten werden im Moment an so genannten IO-gebundenen Tasks ausgeführt, Tasks, die auf Eingabe oder Ausgabe warten. Dies wird normalerweise durch die Verwendung von Abruf- und Timeout-basierten Funktionen erreicht, die aufgerufen werden können, und wenn sie negativ zurückkehren, kann der Kontext umgeschaltet werden.
Trotz des Namens könnte dies auf CPU-gebunden Aufgaben auch angewendet werden, die an einen anderen Arbeiter (Thread, Prozess, etc) delegiert werden können und dann non-blockingly warten, um zu ergeben. Idealerweise würden diese Aufgaben auf eine asynchrone Art und Weise geschrieben werden, aber realistisch würde dies bedeuten, dass der Code in ausreichend kleine Blöcke aufgeteilt wird, um nicht zu blockieren, vorzugsweise ohne Kontextschalter nach jeder Codezeile zu streuen. Dies ist insbesondere für existierende synchrone Bibliotheken unbequem.
Aufgrund der Bequemlichkeit, ließ ich mich GEVENT für asynchrones Arbeiten mit und frage mich, wie mit CPU-gebundene Aufgaben in einem Asynchron-Umgebung (mit Futures, Sellerie, etc?) Behandelt werden soll.
Wie verwenden Sie asynchrone Ausführungsmodelle (gevent in diesem Fall) mit herkömmlichen Web-Frameworks wie z. Was sind gängige Lösungen für diese Probleme in Python (Futures, Task Queues)?
EDIT: Um genauer zu sein - Wie gevent mit Kolben zu verwenden und wie mit CPU-gebundenen Aufgaben in diesem Zusammenhang umgehen?
EDIT2: Wenn man bedenkt, wie Python die GIL hat, die die optimale Ausführung von threaded Code verhindert, bleibt nur die Multiprocessing Option, in meinem Fall zumindest.Dies bedeutet, entweder gleichzeitige.Futuren oder einen anderen externen Service zu verwenden Verarbeitung (kann die Türen für sogar etwas Sprache Agnostiker öffnen). Was wären in diesem Fall einige beliebte oder häufig verwendete Lösungen mit gevent (, d. H. Sellerie)? - Best Practices
Sie können dieses Muster in fast jede Bibliothek übernehmen: http://bottlepy.org/docs/dev/async.html#event-callbacks. Ich würde "Evergreen" vorschlagen, weil es die Kombination von kooperativen Aufgaben (Greenlets) mit lang laufenden Aufgaben durch die Integration einer modifizierten Version von 'concurrent.futures' ermöglicht. – schlamar