Inhaltsverzeichnis
Fazit
Heim Backend-Entwicklung Python-Tutorial Einführung in BlockBuster: Ist meine Asyncio-Ereignisschleife blockiert?

Einführung in BlockBuster: Ist meine Asyncio-Ereignisschleife blockiert?

Jan 09, 2025 am 06:29 AM

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())
Nach dem Login kopieren
Nach dem Login kopieren

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>
Nach dem Login kopieren
Nach dem Login kopieren

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())
Nach dem Login kopieren
Nach dem Login kopieren

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>
Nach dem Login kopieren

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")
Nach dem Login kopieren

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())
Nach dem Login kopieren
Nach dem Login kopieren

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>
Nach dem Login kopieren
Nach dem Login kopieren

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())
Nach dem Login kopieren
Nach dem Login kopieren

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!

Erklärung dieser Website
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

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

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Python vs. C: Anwendungen und Anwendungsfälle verglichen Python vs. C: Anwendungen und Anwendungsfälle verglichen Apr 12, 2025 am 12:01 AM

Python eignet sich für Datenwissenschafts-, Webentwicklungs- und Automatisierungsaufgaben, während C für Systemprogrammierung, Spieleentwicklung und eingebettete Systeme geeignet ist. Python ist bekannt für seine Einfachheit und sein starkes Ökosystem, während C für seine hohen Leistung und die zugrunde liegenden Kontrollfunktionen bekannt ist.

Wie viel Python können Sie in 2 Stunden lernen? Wie viel Python können Sie in 2 Stunden lernen? Apr 09, 2025 pm 04:33 PM

Sie können die Grundlagen von Python innerhalb von zwei Stunden lernen. 1. Lernen Sie Variablen und Datentypen, 2. Master -Steuerungsstrukturen wie wenn Aussagen und Schleifen, 3. Verstehen Sie die Definition und Verwendung von Funktionen. Diese werden Ihnen helfen, einfache Python -Programme zu schreiben.

Python: Spiele, GUIs und mehr Python: Spiele, GUIs und mehr Apr 13, 2025 am 12:14 AM

Python zeichnet sich in Gaming und GUI -Entwicklung aus. 1) Spielentwicklung verwendet Pygame, die Zeichnungen, Audio- und andere Funktionen bereitstellt, die für die Erstellung von 2D -Spielen geeignet sind. 2) Die GUI -Entwicklung kann Tkinter oder Pyqt auswählen. Tkinter ist einfach und einfach zu bedienen. PYQT hat reichhaltige Funktionen und ist für die berufliche Entwicklung geeignet.

Der 2-stündige Python-Plan: ein realistischer Ansatz Der 2-stündige Python-Plan: ein realistischer Ansatz Apr 11, 2025 am 12:04 AM

Sie können grundlegende Programmierkonzepte und Fähigkeiten von Python innerhalb von 2 Stunden lernen. 1. Lernen Sie Variablen und Datentypen, 2. Master Control Flow (bedingte Anweisungen und Schleifen), 3.. Verstehen Sie die Definition und Verwendung von Funktionen, 4. Beginnen Sie schnell mit der Python -Programmierung durch einfache Beispiele und Code -Snippets.

Python: Erforschen der primären Anwendungen Python: Erforschen der primären Anwendungen Apr 10, 2025 am 09:41 AM

Python wird in den Bereichen Webentwicklung, Datenwissenschaft, maschinelles Lernen, Automatisierung und Skripten häufig verwendet. 1) In der Webentwicklung vereinfachen Django und Flask Frameworks den Entwicklungsprozess. 2) In den Bereichen Datenwissenschaft und maschinelles Lernen bieten Numpy-, Pandas-, Scikit-Learn- und TensorFlow-Bibliotheken eine starke Unterstützung. 3) In Bezug auf Automatisierung und Skript ist Python für Aufgaben wie automatisiertes Test und Systemmanagement geeignet.

Python vs. C: Lernkurven und Benutzerfreundlichkeit Python vs. C: Lernkurven und Benutzerfreundlichkeit Apr 19, 2025 am 12:20 AM

Python ist leichter zu lernen und zu verwenden, während C leistungsfähiger, aber komplexer ist. 1. Python -Syntax ist prägnant und für Anfänger geeignet. Durch die dynamische Tippen und die automatische Speicherverwaltung können Sie die Verwendung einfach zu verwenden, kann jedoch zur Laufzeitfehler führen. 2.C bietet Steuerung und erweiterte Funktionen auf niedrigem Niveau, geeignet für Hochleistungsanwendungen, hat jedoch einen hohen Lernschwellenwert und erfordert manuellem Speicher und Typensicherheitsmanagement.

Python und Zeit: Machen Sie das Beste aus Ihrer Studienzeit Python und Zeit: Machen Sie das Beste aus Ihrer Studienzeit Apr 14, 2025 am 12:02 AM

Um die Effizienz des Lernens von Python in einer begrenzten Zeit zu maximieren, können Sie Pythons DateTime-, Zeit- und Zeitplanmodule verwenden. 1. Das DateTime -Modul wird verwendet, um die Lernzeit aufzuzeichnen und zu planen. 2. Das Zeitmodul hilft, die Studie zu setzen und Zeit zu ruhen. 3. Das Zeitplanmodul arrangiert automatisch wöchentliche Lernaufgaben.

Python: Automatisierung, Skript- und Aufgabenverwaltung Python: Automatisierung, Skript- und Aufgabenverwaltung Apr 16, 2025 am 12:14 AM

Python zeichnet sich in Automatisierung, Skript und Aufgabenverwaltung aus. 1) Automatisierung: Die Sicherungssicherung wird durch Standardbibliotheken wie OS und Shutil realisiert. 2) Skriptschreiben: Verwenden Sie die PSUTIL -Bibliothek, um die Systemressourcen zu überwachen. 3) Aufgabenverwaltung: Verwenden Sie die Zeitplanbibliothek, um Aufgaben zu planen. Die Benutzerfreundlichkeit von Python und die Unterstützung der reichhaltigen Bibliothek machen es zum bevorzugten Werkzeug in diesen Bereichen.

See all articles