suchen
HeimBackend-EntwicklungPython-TutorialEinführung in BlockBuster: Ist meine Asyncio-Ereignisschleife blockiert?

Introducing BlockBuster: is my asyncio event loop blocked?

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

installieren
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 einer conftest.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!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal?Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal?Apr 01, 2025 pm 05:09 PM

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 ...

Wie benutze ich eine schöne Suppe, um HTML zu analysieren?Wie benutze ich eine schöne Suppe, um HTML zu analysieren?Mar 10, 2025 pm 06:54 PM

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)

Mathematische Module in Python: StatistikMathematische Module in Python: StatistikMar 09, 2025 am 11:40 AM

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

Wie führe ich ein tiefes Lernen mit Tensorflow oder Pytorch durch?Wie führe ich ein tiefes Lernen mit Tensorflow oder Pytorch durch?Mar 10, 2025 pm 06:52 PM

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

Was sind einige beliebte Python -Bibliotheken und ihre Verwendung?Was sind einige beliebte Python -Bibliotheken und ihre Verwendung?Mar 21, 2025 pm 06:46 PM

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

Wie erstelle ich Befehlszeilenschnittstellen (CLIS) mit Python?Wie erstelle ich Befehlszeilenschnittstellen (CLIS) mit Python?Mar 10, 2025 pm 06:48 PM

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.

Wie kann ich die gesamte Spalte eines Datenrahmens effizient in einen anderen Datenrahmen mit verschiedenen Strukturen in Python kopieren?Wie kann ich die gesamte Spalte eines Datenrahmens effizient in einen anderen Datenrahmen mit verschiedenen Strukturen in Python kopieren?Apr 01, 2025 pm 11:15 PM

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 ...

Erklären Sie den Zweck virtueller Umgebungen in Python.Erklären Sie den Zweck virtueller Umgebungen in Python.Mar 19, 2025 pm 02:27 PM

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.

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

MinGW – Minimalistisches GNU für Windows

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

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

SAP NetWeaver Server-Adapter für Eclipse

Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.

SublimeText3 Englische Version

SublimeText3 Englische Version

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

mPDF

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),