


Python 3.5 führte asynchrone E/A als Alternative zu Threads zur Handhabung der Parallelität ein. Der Vorteil der asynchronen E/A und der Asyncio-Implementierung in Python besteht darin, dass das System weniger Ressourcen verbraucht und skalierbarer ist, da keine speicherintensiven Betriebssystem-Threads erzeugt werden. Darüber hinaus werden bei Asyncio Planungspunkte klar über die await
-Syntax definiert, während bei Thread-basierter Parallelität die GIL an unvorhersehbaren Codepunkten freigegeben werden kann. Dadurch sind Asyncio-basierte Parallelitätssysteme einfacher zu verstehen und zu debuggen. Schließlich kann die Asyncio-Aufgabe abgebrochen werden, was bei der Verwendung von Threads nicht einfach ist.
Um diese Vorteile wirklich nutzen zu können, ist es jedoch wichtig, das Blockieren von Aufrufen in asynchronen Coroutinen zu vermeiden. Blockierende Aufrufe können Netzwerkaufrufe, Dateisystemaufrufe, sleep
-Aufrufe usw. sein. Diese blockierenden Aufrufe sind schädlich, da Asyncio unter der Haube eine Single-Thread-Ereignisschleife verwendet, um Coroutinen gleichzeitig auszuführen. Wenn Sie also einen blockierenden Aufruf in einer Coroutine durchführen, blockiert dieser die gesamte Ereignisschleife und alle Coroutinen, was sich auf die Gesamtleistung Ihrer Anwendung auswirkt.
Das Folgende ist ein Beispiel für einen Blockierungsaufruf, der verhindert, dass Code gleichzeitig ausgeführt wird:
import asyncio import datetime import time async def example(name): print(f"{datetime.datetime.now()}: {name} start") time.sleep(1) # time.sleep 是一个阻塞函数 print(f"{datetime.datetime.now()}: {name} stop") async def main(): await asyncio.gather(example("1"), example("2")) asyncio.run(main())
Das Laufergebnis ist ähnlich wie:
<code>2025-01-07 18:50:15.327677: 1 start 2025-01-07 18:50:16.328330: 1 stop 2025-01-07 18:50:16.328404: 2 start 2025-01-07 18:50:17.333159: 2 stop</code>
Wie Sie sehen können, laufen die beiden Coroutinen nicht gleichzeitig.
Um dieses Problem zu lösen, müssen Sie ein nicht blockierendes Äquivalent verwenden oder die Ausführung auf den Thread-Pool verschieben:
import asyncio import datetime import time async def example(name): print(f"{datetime.datetime.now()}: {name} start") await asyncio.sleep(1) # 将阻塞的 time.sleep 调用替换为非阻塞的 asyncio.sleep 协程 print(f"{datetime.datetime.now()}: {name} stop") async def main(): await asyncio.gather(example("1"), example("2")) asyncio.run(main())
Das Laufergebnis ist ähnlich wie:
<code>2025-01-07 18:53:53.579738: 1 start 2025-01-07 18:53:53.579797: 2 start 2025-01-07 18:53:54.580463: 1 stop 2025-01-07 18:53:54.580572: 2 stop</code>
Hier laufen zwei Coroutinen gleichzeitig.
Das Problem besteht nun darin, dass es nicht immer einfach ist zu erkennen, ob eine Methode blockiert oder nicht. Vor allem, wenn die Codebasis groß ist oder Bibliotheken von Drittanbietern verwendet. Manchmal werden blockierende Aufrufe in tiefen Teilen des Codes durchgeführt.
Blockiert dieser Code beispielsweise?
import blockbuster from importlib.metadata import version async def get_version(): return version("blockbuster")
Lädt Python beim Start Paketmetadaten in den Speicher? Ist dies erledigt, wenn das Modul blockbuster
geladen wird? Oder wenn wir version()
anrufen? Werden die Ergebnisse zwischengespeichert und sind nachfolgende Aufrufe nicht blockierend? Die richtige Antwort erfolgt beim Aufruf von version()
, was das Lesen der METADATA-Datei des installierten Pakets beinhaltet. Und die Ergebnisse werden nicht zwischengespeichert. Daher ist version()
ein blockierender Aufruf und sollte immer an den Thread verschoben werden. Es ist schwer, diese Tatsache zu erkennen, ohne sich mit dem Code von importlib
auseinanderzusetzen.
Eine Möglichkeit, blockierende Aufrufe zu erkennen, besteht darin, den Debug-Modus von Asyncio zu aktivieren, um blockierende Aufrufe zu protokollieren, die zu lange dauern. Dies ist jedoch nicht der effizienteste Ansatz, da viele Blockierungszeiten, die kürzer als das Trigger-Timeout sind, immer noch die Leistung beeinträchtigen und die Blockierungszeiten im Test/in der Entwicklung möglicherweise anders sind als in der Produktion. Beispielsweise können Datenbankaufrufe in einer Produktionsumgebung länger dauern, wenn die Datenbank große Datenmengen abrufen muss.
Hier kommt BlockBuster ins Spiel! Bei Aktivierung patcht BlockBuster mehrere blockierende Python-Framework-Methoden, die Fehler auslösen, wenn sie aus der Asyncio-Ereignisschleife aufgerufen werden. Zu den Standard-Patching-Methoden gehören Methoden der Module os
, io
, time
, socket
und sqlite
. Eine vollständige Liste der von BlockBuster erkannten Methoden finden Sie in der Projekt-Readme-Datei. Anschließend können Sie BlockBuster im Unit-Test- oder Entwicklungsmodus aktivieren, um blockierende Aufrufe abzufangen und zu beheben. Wenn Sie die großartige BlockHound-Bibliothek für die JVM kennen, ist es das gleiche Prinzip, aber für Python. BlockHound war dank der Macher eine großartige Inspirationsquelle für BlockBuster.
Sehen wir uns an, wie Sie BlockBuster für das obige Blockierungscode-Snippet verwenden.
Zuerst müssen wir das blockbuster
Paket
import asyncio import datetime import time async def example(name): print(f"{datetime.datetime.now()}: {name} start") time.sleep(1) # time.sleep 是一个阻塞函数 print(f"{datetime.datetime.now()}: {name} stop") async def main(): await asyncio.gather(example("1"), example("2")) asyncio.run(main())
Wir können dann das Pytest-Fixture und die blockbuster_ctx()
-Methode verwenden, um den BlockBuster zu Beginn jedes Tests zu aktivieren und ihn während des Teardowns zu deaktivieren.
<code>2025-01-07 18:50:15.327677: 1 start 2025-01-07 18:50:16.328330: 1 stop 2025-01-07 18:50:16.328404: 2 start 2025-01-07 18:50:17.333159: 2 stop</code>
Wenn Sie dies mit Pytest ausführen, erhalten Sie
import asyncio import datetime import time async def example(name): print(f"{datetime.datetime.now()}: {name} start") await asyncio.sleep(1) # 将阻塞的 time.sleep 调用替换为非阻塞的 asyncio.sleep 协程 print(f"{datetime.datetime.now()}: {name} stop") async def main(): await asyncio.gather(example("1"), example("2")) asyncio.run(main())
Hinweis: Typischerweise wird in einem realen Projekt das
blockbuster()
-Gerät in einerconftest.py
-Datei eingerichtet.
Fazit
Ich glaube, dass BlockBuster in Asyncio-Projekten sehr nützlich ist. Es hat mir geholfen, viele Probleme mit blockierenden Anrufen in Projekten, an denen ich gearbeitet habe, zu erkennen. Aber es ist kein Allheilmittel. Insbesondere verwenden einige Bibliotheken von Drittanbietern keine Python-Framework-Methoden für die Interaktion mit dem Netzwerk oder Dateisystem, sondern umschließen stattdessen C-Bibliotheken. Für diese Bibliotheken können Sie in Ihrem Test-Setup Regeln hinzufügen, um blockierende Aufrufe an diese Bibliotheken auszulösen. BlockBuster ist ebenfalls Open Source: Beiträge sind herzlich willkommen, um Regeln für Ihre Lieblingsbibliotheken im Kernprojekt hinzuzufügen. Wenn Sie Probleme und Verbesserungsmöglichkeiten sehen, würde ich mich über Ihr Feedback im Projekt-Issue-Tracker freuen.
Einige Links:
- GitHub-Projekt
- Frage
- Pakete auf Pypi
Das obige ist der detaillierte Inhalt vonEinführung in BlockBuster: Ist meine Asyncio-Ereignisschleife blockiert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Lösung für Erlaubnisprobleme beim Betrachten der Python -Version in Linux Terminal Wenn Sie versuchen, die Python -Version in Linux Terminal anzuzeigen, geben Sie Python ein ...

In diesem Artikel wird erklärt, wie man schöne Suppe, eine Python -Bibliothek, verwendet, um HTML zu analysieren. Es beschreibt gemeinsame Methoden wie find (), find_all (), select () und get_text () für die Datenextraktion, die Behandlung verschiedener HTML -Strukturen und -Anternativen (SEL)

Das Statistikmodul von Python bietet leistungsstarke Datenstatistikanalysefunktionen, mit denen wir die allgemeinen Merkmale von Daten wie Biostatistik und Geschäftsanalyse schnell verstehen können. Anstatt Datenpunkte nacheinander zu betrachten, schauen Sie sich nur Statistiken wie Mittelwert oder Varianz an, um Trends und Merkmale in den ursprünglichen Daten zu ermitteln, die möglicherweise ignoriert werden, und vergleichen Sie große Datensätze einfacher und effektiv. In diesem Tutorial wird erläutert, wie der Mittelwert berechnet und den Grad der Dispersion des Datensatzes gemessen wird. Sofern nicht anders angegeben, unterstützen alle Funktionen in diesem Modul die Berechnung der Mittelwert () -Funktion, anstatt einfach den Durchschnitt zu summieren. Es können auch schwimmende Punktzahlen verwendet werden. zufällig importieren Statistiken importieren Aus Fracti

Dieser Artikel vergleicht TensorFlow und Pytorch für Deep Learning. Es beschreibt die beteiligten Schritte: Datenvorbereitung, Modellbildung, Schulung, Bewertung und Bereitstellung. Wichtige Unterschiede zwischen den Frameworks, insbesondere bezüglich des rechnerischen Graps

In dem Artikel werden beliebte Python-Bibliotheken wie Numpy, Pandas, Matplotlib, Scikit-Learn, TensorFlow, Django, Flask und Anfragen erörtert, die ihre Verwendung in wissenschaftlichen Computing, Datenanalyse, Visualisierung, maschinellem Lernen, Webentwicklung und h beschreiben

Dieser Artikel führt die Python-Entwickler in den Bauen von CLIS-Zeilen-Schnittstellen (CLIS). Es werden mit Bibliotheken wie Typer, Click und ArgParse beschrieben, die Eingabe-/Ausgabemedelung betonen und benutzerfreundliche Designmuster für eine verbesserte CLI-Usabilität fördern.

Bei der Verwendung von Pythons Pandas -Bibliothek ist das Kopieren von ganzen Spalten zwischen zwei Datenrahmen mit unterschiedlichen Strukturen ein häufiges Problem. Angenommen, wir haben zwei Daten ...

Der Artikel erörtert die Rolle virtueller Umgebungen in Python und konzentriert sich auf die Verwaltung von Projektabhängigkeiten und die Vermeidung von Konflikten. Es beschreibt ihre Erstellung, Aktivierung und Vorteile bei der Verbesserung des Projektmanagements und zur Verringerung der Abhängigkeitsprobleme.


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

MinGW – Minimalistisches GNU für Windows
Dieses Projekt wird derzeit auf osdn.net/projects/mingw migriert. Sie können uns dort weiterhin folgen. MinGW: Eine native Windows-Portierung der GNU Compiler Collection (GCC), frei verteilbare Importbibliotheken und Header-Dateien zum Erstellen nativer Windows-Anwendungen, einschließlich Erweiterungen der MSVC-Laufzeit zur Unterstützung der C99-Funktionalität. Die gesamte MinGW-Software kann auf 64-Bit-Windows-Plattformen ausgeführt werden.

Sicherer Prüfungsbrowser
Safe Exam Browser ist eine sichere Browserumgebung für die sichere Teilnahme an Online-Prüfungen. Diese Software verwandelt jeden Computer in einen sicheren Arbeitsplatz. Es kontrolliert den Zugriff auf alle Dienstprogramme und verhindert, dass Schüler nicht autorisierte Ressourcen nutzen.

SAP NetWeaver Server-Adapter für Eclipse
Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.

SublimeText3 Englische Version
Empfohlen: Win-Version, unterstützt Code-Eingabeaufforderungen!

mPDF
mPDF ist eine PHP-Bibliothek, die PDF-Dateien aus UTF-8-codiertem HTML generieren kann. Der ursprüngliche Autor, Ian Back, hat mPDF geschrieben, um PDF-Dateien „on the fly“ von seiner Website auszugeben und verschiedene Sprachen zu verarbeiten. Es ist langsamer und erzeugt bei der Verwendung von Unicode-Schriftarten größere Dateien als Originalskripte wie HTML2FPDF, unterstützt aber CSS-Stile usw. und verfügt über viele Verbesserungen. Unterstützt fast alle Sprachen, einschließlich RTL (Arabisch und Hebräisch) und CJK (Chinesisch, Japanisch und Koreanisch). Unterstützt verschachtelte Elemente auf Blockebene (wie P, DIV),