Event Loop¶
Quellcode: Lib/asyncio/events.py, Lib/asyncio/base_events.py
Vorwort
Die Event-Schleife ist der Kern jeder asyncio-Anwendung. Event-Schleifen führen asynchrone Tasks und Callbacks aus, führen Netzwerk-I/O-Operationen durch und führen Subprozesse aus.
Anwendungsentwickler sollten in der Regel die High-Level-Funktionen von asyncio verwenden, wie z. B. asyncio.run(), und sollten selten auf das Schleifenobjekt verweisen oder dessen Methoden aufrufen müssen. Dieser Abschnitt richtet sich hauptsächlich an Autoren von Low-Level-Code, Bibliotheken und Frameworks, die eine feinere Kontrolle über das Verhalten der Event-Schleife benötigen.
Die Event Loop erhalten
Die folgenden Low-Level-Funktionen können verwendet werden, um eine Event-Schleife abzurufen, festzulegen oder zu erstellen
- asyncio.get_running_loop()¶
Gibt die laufende Event-Schleife im aktuellen Betriebssystem-Thread zurück.
Löst einen
RuntimeErroraus, wenn keine laufende Event-Schleife vorhanden ist.Diese Funktion kann nur von einem Korutin oder einem Callback aufgerufen werden.
Hinzugefügt in Version 3.7.
- asyncio.get_event_loop()¶
Holt die aktuelle Event-Schleife.
Wenn von einer Korutin oder einem Callback aufgerufen (z. B. geplant mit call_soon oder ähnlicher API), gibt diese Funktion immer die laufende Event-Schleife zurück.
Wenn keine laufende Event-Schleife gesetzt ist, gibt die Funktion das Ergebnis des Aufrufs
get_event_loop_policy().get_event_loop()zurück.Da diese Funktion ein recht komplexes Verhalten aufweist (insbesondere bei benutzerdefinierten Event-Loop-Richtlinien), ist die Verwendung der Funktion
get_running_loop()für Korutinen und Callbacks der Funktionget_event_loop()vorzuziehen.Wie oben erwähnt, sollten Sie die High-Level-Funktion
asyncio.run()in Betracht ziehen, anstatt diese Low-Level-Funktionen zum manuellen Erstellen und Schließen einer Event-Schleife zu verwenden.Geändert in Version 3.14: Löst einen
RuntimeErroraus, wenn keine aktuelle Event-Schleife vorhanden ist.Hinweis
Das Richtliniensystem von
asyncioist veraltet und wird in Python 3.16 entfernt. Ab dann gibt diese Funktion die aktuelle laufende Event-Schleife zurück, falls vorhanden, andernfalls gibt sie die Schleife zurück, die vonset_event_loop()gesetzt wurde.
- asyncio.set_event_loop(loop)¶
Setzt loop als die aktuelle Event-Schleife für den aktuellen Betriebssystem-Thread.
- asyncio.new_event_loop()¶
Erstellt und gibt ein neues Event-Loop-Objekt zurück.
Beachten Sie, dass das Verhalten der Funktionen get_event_loop(), set_event_loop() und new_event_loop() durch das Festlegen einer benutzerdefinierten Event-Loop-Richtlinie geändert werden kann.
Inhalt
Diese Dokumentationsseite enthält die folgenden Abschnitte
Der Abschnitt Event Loop Methods ist die Referenzdokumentation der Event-Loop-APIs;
Der Abschnitt Callback Handles dokumentiert die Instanzen von
HandleundTimerHandle, die von Planungs-Methoden wieloop.call_soon()undloop.call_later()zurückgegeben werden;Der Abschnitt Server Objects dokumentiert die Typen, die von Event-Loop-Methoden wie
loop.create_server()zurückgegeben werden;Der Abschnitt Event Loop Implementations dokumentiert die Klassen
SelectorEventLoopundProactorEventLoop;Der Abschnitt Examples zeigt, wie mit einigen Event-Loop-APIs gearbeitet wird.
Event Loop Methods¶
Event-Schleifen haben **Low-Level**-APIs für Folgendes
Schleife ausführen und stoppen¶
- loop.run_until_complete(future)¶
Läuft, bis der future (eine Instanz von
Future) abgeschlossen ist.Wenn das Argument ein Korutin-Objekt ist, wird es implizit als
asyncio.Taskgeplant.Gibt das Ergebnis des Future zurück oder löst dessen Ausnahme aus.
- loop.run_forever()¶
Führt die Event-Schleife aus, bis
stop()aufgerufen wird.Wenn
stop()aufgerufen wird, bevorrun_forever()aufgerufen wird, pollt die Schleife einmal den I/O-Selektor mit einem Timeout von Null, führt alle Callbacks aus, die als Reaktion auf I/O-Ereignisse geplant wurden (und die, die bereits geplant waren), und beendet sich dann.Wenn
stop()aufgerufen wird, währendrun_forever()läuft, führt die Schleife den aktuellen Satz von Callbacks aus und beendet sich dann. Beachten Sie, dass neu geplante Callbacks in diesem Fall nicht ausgeführt werden; stattdessen werden sie beim nächsten Aufruf vonrun_forever()oderrun_until_complete()ausgeführt.
- loop.stop()¶
Stoppt die Event-Schleife.
- loop.is_running()¶
Gibt
Truezurück, wenn die Event-Schleife gerade ausgeführt wird.
- loop.is_closed()¶
Gibt
Truezurück, wenn die Event-Schleife geschlossen wurde.
- loop.close()¶
Schließt die Event-Schleife.
Die Schleife darf beim Aufruf dieser Funktion nicht ausgeführt werden. Alle ausstehenden Callbacks werden verworfen.
Diese Methode leert alle Warteschlangen und fährt den Executor herunter, wartet jedoch nicht darauf, dass der Executor seine Ausführung beendet.
Diese Methode ist idempotent und unwiderruflich. Nach dem Schließen der Event-Schleife sollten keine anderen Methoden mehr aufgerufen werden.
- async loop.shutdown_asyncgens()¶
Plant, alle aktuell geöffneten asynchronen Generator-Objekte mit einem Aufruf von
aclose()zu schließen. Nach dem Aufruf dieser Methode gibt die Event-Schleife eine Warnung aus, wenn ein neuer asynchroner Generator iteriert wird. Dies sollte verwendet werden, um alle geplanten asynchronen Generatoren zuverlässig zu finalisieren.Beachten Sie, dass diese Funktion nicht aufgerufen werden muss, wenn
asyncio.run()verwendet wird.Beispiel
try: loop.run_forever() finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()
Hinzugefügt in Version 3.6.
- async loop.shutdown_default_executor(timeout=None)¶
Plant das Schließen des Standard-Executors und wartet darauf, dass er alle Threads im
ThreadPoolExecutorzusammenführt. Nach dem Aufruf dieser Methode löst die Verwendung des Standard-Executors mitloop.run_in_executor()einenRuntimeErroraus.Der Parameter timeout gibt an, wie viel Zeit (in
floatSekunden) der Executor zum Beenden des Zusammenführens erhält. Mit dem StandardwertNonedarf der Executor unbegrenzt viel Zeit beanspruchen.Wenn der timeout erreicht wird, wird eine
RuntimeWarningausgegeben und der Standard-Executor wird beendet, ohne darauf zu warten, dass seine Threads zusammengeführt werden.Hinweis
Rufen Sie diese Methode nicht auf, wenn
asyncio.run()verwendet wird, da letztere das Herunterfahren des Standard-Executors automatisch handhabt.Hinzugefügt in Version 3.9.
Geändert in Version 3.12: Der Parameter timeout wurde hinzugefügt.
Callbacks planen¶
- loop.call_soon(callback, *args, context=None)¶
Plant, dass der callback Callback mit den args Argumenten bei der nächsten Iteration der Event-Schleife aufgerufen wird.
Gibt eine Instanz von
asyncio.Handlezurück, die später zum Abbrechen des Callbacks verwendet werden kann.Callbacks werden in der Reihenfolge aufgerufen, in der sie registriert werden. Jeder Callback wird genau einmal aufgerufen.
Das optionale schlüsselwort-nur context Argument gibt einen benutzerdefinierten
contextvars.Contextan, in dem der callback ausgeführt werden soll. Callbacks verwenden den aktuellen Kontext, wenn kein context angegeben wird.Im Gegensatz zu
call_soon_threadsafe()ist diese Methode nicht threadsicher.
- loop.call_soon_threadsafe(callback, *args, context=None)¶
Eine threadsichere Variante von
call_soon(). Beim Planen von Callbacks aus einem anderen Thread *muss* diese Funktion verwendet werden, dacall_soon()nicht threadsicher ist.Diese Funktion ist sicher aus einem reentranten Kontext oder Signalhandler aufrufbar, jedoch ist es nicht sicher oder nützlich, das zurückgegebene Handle in solchen Kontexten zu verwenden.
Löst
RuntimeErroraus, wenn sie auf einer geschlossenen Schleife aufgerufen wird. Dies kann auf einem sekundären Thread geschehen, wenn die Hauptanwendung heruntergefahren wird.Siehe den Abschnitt über Nebenläufigkeit und Multithreading in der Dokumentation.
Geändert in Version 3.7: Der schlüsselwort-nur Parameter context wurde hinzugefügt. Siehe PEP 567 für weitere Details.
Hinweis
Die meisten asyncio-Planungsfunktionen erlauben keine Übergabe von Schlüsselwortargumenten. Verwenden Sie hierfür functools.partial()
# will schedule "print("Hello", flush=True)"
loop.call_soon(
functools.partial(print, "Hello", flush=True))
Die Verwendung von Partial-Objekten ist normalerweise bequemer als die Verwendung von Lambdas, da asyncio Partial-Objekte in Debug- und Fehlermeldungen besser darstellen kann.
Verzögerte Callbacks planen¶
Die Event-Schleife bietet Mechanismen, um Callback-Funktionen zu planen, die zu einem späteren Zeitpunkt ausgeführt werden sollen. Die Event-Schleife verwendet mononische Uhren, um die Zeit zu verfolgen.
- loop.call_later(delay, callback, *args, context=None)¶
Plant, dass callback nach der angegebenen delay Anzahl von Sekunden (kann eine Ganzzahl oder eine Gleitkommazahl sein) aufgerufen wird.
Eine Instanz von
asyncio.TimerHandlewird zurückgegeben, die zum Abbrechen des Callbacks verwendet werden kann.callback wird genau einmal aufgerufen. Wenn zwei Callbacks für genau dieselbe Zeit geplant sind, ist die Reihenfolge, in der sie aufgerufen werden, undefiniert.
Die optionalen positionsbezogenen args werden an den Callback übergeben, wenn er aufgerufen wird. Wenn Sie möchten, dass der Callback mit Schlüsselwortargumenten aufgerufen wird, verwenden Sie
functools.partial().Ein optionales schlüsselwort-nur context Argument erlaubt die Angabe eines benutzerdefinierten
contextvars.Context, in dem der callback ausgeführt werden soll. Der aktuelle Kontext wird verwendet, wenn kein context angegeben wird.Hinweis
Aus Performance-Gründen können Callbacks, die mit
loop.call_later()geplant wurden, bis zu einer Takt-Auflösung frühzeitig ausgeführt werden (siehetime.get_clock_info('monotonic').resolution).Geändert in Version 3.7: Der schlüsselwort-nur Parameter context wurde hinzugefügt. Siehe PEP 567 für weitere Details.
Geändert in Version 3.8: In Python 3.7 und früheren Versionen mit der Standard-Event-Loop-Implementierung konnte die delay nicht länger als ein Tag sein. Dies wurde in Python 3.8 behoben.
- loop.call_at(when, callback, *args, context=None)¶
Plant, dass callback zum angegebenen absoluten Zeitstempel when (eine Ganzzahl oder Gleitkommazahl) aufgerufen wird, unter Verwendung derselben Zeitreferenz wie
loop.time().Das Verhalten dieser Methode ist dasselbe wie bei
call_later().Eine Instanz von
asyncio.TimerHandlewird zurückgegeben, die zum Abbrechen des Callbacks verwendet werden kann.Hinweis
Aus Performance-Gründen können Callbacks, die mit
loop.call_at()geplant wurden, bis zu einer Takt-Auflösung frühzeitig ausgeführt werden (siehetime.get_clock_info('monotonic').resolution).Geändert in Version 3.7: Der schlüsselwort-nur Parameter context wurde hinzugefügt. Siehe PEP 567 für weitere Details.
Geändert in Version 3.8: In Python 3.7 und früheren Versionen mit der Standard-Event-Loop-Implementierung konnte die Differenz zwischen when und der aktuellen Zeit nicht länger als ein Tag sein. Dies wurde in Python 3.8 behoben.
- loop.time()¶
Gibt die aktuelle Zeit als Gleitkommazahl zurück, gemäß der internen mononischen Uhr der Event-Schleife.
Hinweis
Geändert in Version 3.8: In Python 3.7 und früheren Versionen durften Timeouts (relative delay oder absolute when) nicht länger als ein Tag sein. Dies wurde in Python 3.8 behoben.
Siehe auch
Die Funktion asyncio.sleep().
Futures und Tasks erstellen¶
- loop.create_future()¶
Erstellt ein
asyncio.Future-Objekt, das an die Event-Schleife gebunden ist.Dies ist der bevorzugte Weg, Futures in asyncio zu erstellen. Dies ermöglicht Drittanbieter-Event-Schleifen, alternative Implementierungen des Future-Objekts bereitzustellen (mit besserer Leistung oder Instrumentierung).
Hinzugefügt in Version 3.5.2.
- loop.create_task(coro, *, name=None, context=None, eager_start=None, **kwargs)¶
Plant die Ausführung der Korutin coro. Gibt ein
Task-Objekt zurück.Drittanbieter-Event-Schleifen können ihre eigenen Unterklassen von
Taskfür die Interoperabilität verwenden. In diesem Fall ist der Ergebnistyp eine Unterklasse vonTask.Die vollständige Funktionssignatur ist weitgehend dieselbe wie die des Konstruktors von
Task(oder Factory) – alle Schlüsselwortargumente dieser Funktion werden an diese Schnittstelle weitergegeben.Wenn das Argument name angegeben und nicht
Noneist, wird es als Name des Tasks mitTask.set_name()gesetzt.Ein optionales schlüsselwort-nur context Argument erlaubt die Angabe eines benutzerdefinierten
contextvars.Context, in dem coro ausgeführt werden soll. Die aktuelle Kontextkopie wird erstellt, wenn kein context angegeben wird.Ein optionales schlüsselwort-nur eager_start Argument erlaubt die Angabe, ob der Task beim Aufruf von create_task sofort ausgeführt werden soll oder später geplant werden soll. Wenn eager_start nicht übergeben wird, wird der Modus verwendet, der von
loop.set_task_factory()festgelegt wurde.Geändert in Version 3.8: Der Parameter name wurde hinzugefügt.
Geändert in Version 3.11: Der Parameter context wurde hinzugefügt.
Geändert in Version 3.13.3:
kwargshinzugefügt, die beliebige zusätzliche Parameter übergibt, einschließlichnameundcontext.Geändert in Version 3.13.4: Die Änderung, die name und context übergibt (wenn sie None sind), wurde zurückgenommen, während andere beliebige Schlüsselwortargumente weiterhin übergeben werden (um die Abwärtskompatibilität mit 3.13.3 nicht zu brechen).
Geändert in Version 3.14: Alle kwargs werden jetzt weitergegeben. Der Parameter eager_start funktioniert mit eager Task-Factories.
- loop.set_task_factory(factory)¶
Setzt eine Task-Factory, die von
loop.create_task()verwendet wird.Wenn factory
Noneist, wird die Standard-Task-Factory gesetzt. Andernfalls muss factory ein Callable mit der Signatur sein, die mit(loop, coro, **kwargs)übereinstimmt, wobei loop eine Referenz auf die aktive Ereignisschleife ist und coro ein Coroutine-Objekt ist. Das Callable muss alle kwargs weitergeben und einasyncio.Task-kompatibles Objekt zurückgeben.Geändert in Version 3.13.3: Erfordert, dass alle kwargs an
asyncio.Taskweitergegeben werden.Geändert in Version 3.13.4: name wird nicht mehr an Task-Factories übergeben. context wird nicht mehr an Task-Factories übergeben, wenn es
Noneist.Geändert in Version 3.14: name und context werden jetzt wieder bedingungslos an Task-Factories übergeben.
- loop.get_task_factory()¶
Gibt eine Task-Factory zurück oder
None, wenn die Standard-Factory verwendet wird.
Netzwerkverbindungen öffnen¶
- async loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None, all_errors=False)¶
Öffnet eine Streaming-Transportverbindung zu einer bestimmten Adresse, die durch host und port angegeben ist.
Die Socket-Familie kann entweder
AF_INEToderAF_INET6sein, abhängig von host (oder dem Argument family, falls angegeben).Der Socket-Typ ist
SOCK_STREAM.protocol_factory muss ein Callable sein, das eine asyncio-Protokoll-Implementierung zurückgibt.
Diese Methode versucht, die Verbindung im Hintergrund herzustellen. Bei Erfolg gibt sie ein
(transport, protocol)Paar zurück.Der chronologische Ablauf der zugrunde liegenden Operation ist wie folgt:
Die Verbindung wird hergestellt und ein Transport dafür erstellt.
protocol_factory wird ohne Argumente aufgerufen und sollte eine Instanz eines Protokolls zurückgeben.
Die Protokollinstanz wird mit dem Transport gekoppelt, indem ihre Methode
connection_made()aufgerufen wird.Ein Tupel
(transport, protocol)wird bei Erfolg zurückgegeben.
Der erstellte Transport ist ein implementierungsabhängiger bidirektionaler Stream.
Weitere Argumente
ssl: Wenn gegeben und nicht falsch, wird ein SSL/TLS-Transport erstellt (standardmäßig wird ein einfacher TCP-Transport erstellt). Wenn ssl ein
ssl.SSLContext-Objekt ist, wird dieser Kontext zur Erstellung des Transports verwendet; wenn sslTrueist, wird ein Standardkontext vonssl.create_default_context()verwendet.Siehe auch
server_hostname legt den Hostnamen fest oder überschreibt ihn, gegen den das Zertifikat des Zielservers abgeglichen wird. Sollte nur übergeben werden, wenn ssl nicht
Noneist. Standardmäßig wird der Wert des Arguments host verwendet. Wenn host leer ist, gibt es keinen Standardwert und Sie müssen einen Wert für server_hostname übergeben. Wenn server_hostname ein leerer String ist, wird der Abgleich des Hostnamens deaktiviert (was ein ernstes Sicherheitsrisiko darstellt und potenzielle Man-in-the-Middle-Angriffe ermöglicht).family, proto, flags sind die optionalen Adressfamilie, das Protokoll und die Flags, die zur Auflösung von host an getaddrinfo() übergeben werden. Falls angegeben, sollten dies alles Ganzzahlen aus den entsprechenden Konstanten des
socket-Moduls sein.happy_eyeballs_delay, falls angegeben, aktiviert Happy Eyeballs für diese Verbindung. Es sollte eine Gleitkommazahl sein, die die Wartezeit in Sekunden angibt, bis ein Verbindungsversuch abgeschlossen ist, bevor der nächste Versuch parallel gestartet wird. Dies ist die "Connection Attempt Delay", wie in RFC 8305 definiert. Ein sinnvoller Standardwert, der von der RFC empfohlen wird, ist
0.25(250 Millisekunden).interleave steuert die Adressreihenfolge, wenn ein Hostname mehrere IP-Adressen auflöst. Wenn
0oder nicht angegeben, erfolgt keine Neuordnung und die Adressen werden in der vongetaddrinfo()zurückgegebenen Reihenfolge versucht. Wenn eine positive Ganzzahl angegeben wird, werden die Adressen nach Adressfamilie verschachtelt und die angegebene Ganzzahl wird als "First Address Family Count" gemäß RFC 8305 interpretiert. Der Standardwert ist0, wenn happy_eyeballs_delay nicht angegeben ist, und1, wenn es angegeben ist.sock, falls gegeben, sollte ein vorhandenes, bereits verbundenes
socket.socket-Objekt sein, das vom Transport verwendet wird. Wenn sock gegeben ist, sollten host, port, family, proto, flags, happy_eyeballs_delay, interleave und local_addr nicht angegeben werden.Hinweis
Das Argument sock überträgt das Eigentum am Socket an den erstellten Transport. Um den Socket zu schließen, rufen Sie die Methode
close()des Transports auf.local_addr, falls gegeben, ist ein Tupel
(local_host, local_port), das zum lokalen Binden des Sockets verwendet wird. local_host und local_port werden ähnlich wie host und port mitgetaddrinfo()aufgelöst.ssl_handshake_timeout ist (für eine TLS-Verbindung) die Zeit in Sekunden, die auf den Abschluss des TLS-Handshakes gewartet wird, bevor die Verbindung abgebrochen wird.
60.0Sekunden, wennNone(Standard).ssl_shutdown_timeout ist die Zeit in Sekunden, die auf den Abschluss des SSL-Shutdowns gewartet wird, bevor die Verbindung abgebrochen wird.
30.0Sekunden, wennNone(Standard).all_errors bestimmt, welche Ausnahmen ausgelöst werden, wenn eine Verbindung nicht erstellt werden kann. Standardmäßig wird nur eine einzige
Exceptionausgelöst: die erste Ausnahme, wenn es nur eine gibt oder alle Fehler dieselbe Nachricht haben, oder eine einzelneOSErrormit kombinierten Fehlermeldungen. Wennall_errorsTrueist, wird eineExceptionGroupausgelöst, die alle Ausnahmen enthält (auch wenn es nur eine gibt).
Geändert in Version 3.5: Unterstützung für SSL/TLS in
ProactorEventLoophinzugefügt.Geändert in Version 3.6: Die Socket-Option socket.TCP_NODELAY wird standardmäßig für alle TCP-Verbindungen gesetzt.
Geändert in Version 3.7: Der Parameter ssl_handshake_timeout wurde hinzugefügt.
Geändert in Version 3.8: Die Parameter happy_eyeballs_delay und interleave wurden hinzugefügt.
Happy Eyeballs Algorithmus: Erfolg mit Dual-Stack-Hosts. Wenn der IPv4-Pfad und das Protokoll eines Servers funktionieren, aber der IPv6-Pfad und das Protokoll des Servers nicht funktionieren, erfährt eine Dual-Stack-Clientanwendung eine erhebliche Verbindungsverzögerung im Vergleich zu einem IPv4-only-Client. Dies ist unerwünscht, da es dazu führt, dass der Dual-Stack-Client eine schlechtere Benutzererfahrung hat. Dieses Dokument spezifiziert die Anforderungen für Algorithmen, die diese benutzerseitig sichtbare Verzögerung reduzieren, und stellt einen Algorithmus bereit.
Weitere Informationen: https://datatracker.ietf.org/doc/html/rfc6555
Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Geändert in Version 3.12: all_errors wurde hinzugefügt.
Siehe auch
Die Funktion
open_connection()ist eine High-Level-Alternative API. Sie gibt ein Paar aus (StreamReader,StreamWriter) zurück, die direkt in async/await-Code verwendet werden kann.
- async loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_port=None, allow_broadcast=None, sock=None)¶
Erstellt eine Datagrammverbindung.
Die Socket-Familie kann entweder
AF_INET,AF_INET6oderAF_UNIXsein, abhängig von host (oder dem Argument family, falls angegeben).Der Socket-Typ ist
SOCK_DGRAM.protocol_factory muss ein Callable sein, das eine Protokoll-Implementierung zurückgibt.
Ein Tupel aus
(transport, protocol)wird bei Erfolg zurückgegeben.Weitere Argumente
local_addr, falls gegeben, ist ein Tupel
(local_host, local_port), das zum lokalen Binden des Sockets verwendet wird. local_host und local_port werden mitgetaddrinfo()aufgelöst.Hinweis
Unter Windows wird bei der Verwendung der Proactor-Ereignisschleife mit
local_addr=NoneeineOSErrormiterrno.WSAEINVALausgelöst.remote_addr, falls gegeben, ist ein Tupel
(remote_host, remote_port), das zum Verbinden des Sockets mit einer Remote-Adresse verwendet wird. remote_host und remote_port werden mitgetaddrinfo()aufgelöst.family, proto, flags sind die optionalen Adressfamilie, das Protokoll und die Flags, die zur Auflösung von host an
getaddrinfo()übergeben werden. Falls angegeben, sollten dies alles Ganzzahlen aus den entsprechenden Konstanten dessocket-Moduls sein.reuse_port teilt dem Kernel mit, dass dieser Endpunkt an denselben Port gebunden werden darf, an den auch andere vorhandene Endpunkte gebunden sind, vorausgesetzt, alle setzen dieses Flag bei der Erstellung. Diese Option wird unter Windows und einigen Unix-Systemen nicht unterstützt. Wenn die Konstante socket.SO_REUSEPORT nicht definiert ist, ist diese Funktionalität nicht unterstützt.
allow_broadcast teilt dem Kernel mit, dass dieser Endpunkt Nachrichten an die Broadcast-Adresse senden darf.
sock kann optional angegeben werden, um ein bereits vorhandenes, bereits verbundenes
socket.socket-Objekt zu verwenden, das vom Transport genutzt wird. Wenn sock angegeben ist, sollten local_addr und remote_addr weggelassen werden (müssenNonesein).Hinweis
Das Argument sock überträgt das Eigentum am Socket an den erstellten Transport. Um den Socket zu schließen, rufen Sie die Methode
close()des Transports auf.
Siehe die Beispiele UDP Echo-Client-Protokoll und UDP Echo-Server-Protokoll.
Geändert in Version 3.4.4: Die Parameter family, proto, flags, reuse_address, reuse_port, allow_broadcast und sock wurden hinzugefügt.
Geändert in Version 3.8: Unterstützung für Windows hinzugefügt.
Geändert in Version 3.8.1: Der Parameter reuse_address wird nicht mehr unterstützt, da die Verwendung von socket.SO_REUSEADDR ein erhebliches Sicherheitsrisiko für UDP darstellt. Das explizite Übergeben von
reuse_address=Truelöst eine Ausnahme aus.Wenn mehrere Prozesse mit unterschiedlichen UIDs Sockets an dieselbe UDP-Socket-Adresse mit
SO_REUSEADDRbinden, können eingehende Pakete zufällig auf die Sockets verteilt werden.Auf unterstützten Plattformen kann reuse_port als Ersatz für ähnliche Funktionalität verwendet werden. Mit reuse_port wird stattdessen socket.SO_REUSEPORT verwendet, was insbesondere verhindert, dass Prozesse mit unterschiedlichen UIDs Sockets an dieselbe Socket-Adresse binden.
Geändert in Version 3.11: Der Parameter reuse_address, der seit Python 3.8.1, 3.7.6 und 3.6.10 deaktiviert war, wurde vollständig entfernt.
- async loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)¶
Erstellt eine Unix-Verbindung.
Die Socket-Familie ist
AF_UNIX; der Socket-Typ istSOCK_STREAM.Ein Tupel aus
(transport, protocol)wird bei Erfolg zurückgegeben.path ist der Name eines Unix-Domain-Sockets und ist erforderlich, es sei denn, ein sock-Parameter ist angegeben. Abstrakte Unix-Sockets,
str,bytesundPath-Pfade werden unterstützt.Siehe die Dokumentation der Methode
loop.create_connection()für Informationen zu den Argumenten dieser Methode.Verfügbarkeit: Unix.
Geändert in Version 3.7: Der Parameter ssl_handshake_timeout wurde hinzugefügt. Der Parameter path kann jetzt ein pfadähnliches Objekt sein.
Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Netzwerkserver erstellen¶
- async loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)¶
Erstellt einen TCP-Server (Socket-Typ
SOCK_STREAM), der auf port der Adresse host lauscht.Gibt ein
Server-Objekt zurück.Argumente
protocol_factory muss ein Callable sein, das eine Protokoll-Implementierung zurückgibt.
Der Parameter host kann auf verschiedene Arten gesetzt werden, die bestimmen, wo der Server lauschen wird:
Wenn host ein String ist, wird der TCP-Server an eine einzelne Netzwerkschnittstelle gebunden, die durch host angegeben ist.
Wenn host eine Sequenz von Strings ist, wird der TCP-Server an alle durch die Sequenz angegebenen Netzwerkschnittstellen gebunden.
Wenn host ein leerer String oder
Noneist, werden alle Schnittstellen angenommen und eine Liste von mehreren Sockets zurückgegeben (wahrscheinlich einer für IPv4 und ein weiterer für IPv6).
Der Parameter port kann gesetzt werden, um anzugeben, auf welchem Port der Server lauschen soll. Wenn
0oderNone(Standard) angegeben wird, wird ein zufälliger ungenutzter Port ausgewählt (beachten Sie, dass bei Auflösung von host auf mehrere Netzwerkschnittstellen für jede Schnittstelle ein anderer zufälliger Port ausgewählt wird).family kann entweder auf
socket.AF_INETodersocket.AF_INET6gesetzt werden, um den Socket zu zwingen, IPv4 oder IPv6 zu verwenden. Wenn nicht gesetzt, wird die family aus dem Hostnamen ermittelt (Standard istAF_UNSPEC).flags ist eine Bitmaske für
getaddrinfo().sock kann optional angegeben werden, um ein bereits vorhandenes Socket-Objekt zu verwenden. Wenn angegeben, dürfen host und port nicht angegeben werden.
Hinweis
Das Argument sock überträgt das Eigentum am Socket an den erstellten Server. Um den Socket zu schließen, rufen Sie die Methode
close()des Servers auf.backlog ist die maximale Anzahl von Warteschlangen für Verbindungen, die an
listen()übergeben wird (Standard ist 100).ssl kann auf eine
SSLContext-Instanz gesetzt werden, um TLS über die akzeptierten Verbindungen zu aktivieren.reuse_address teilt dem Kernel mit, dass ein lokaler Socket im Zustand
TIME_WAITwiederverwendet werden kann, ohne auf den natürlichen Timeout zu warten. Wenn nicht angegeben, wird unter Unix standardmäßigTruegesetzt.reuse_port teilt dem Kernel mit, dass dieser Endpunkt an denselben Port gebunden werden darf, an den auch andere vorhandene Endpunkte gebunden sind, vorausgesetzt, alle setzen dieses Flag bei der Erstellung. Diese Option wird unter Windows nicht unterstützt.
keep_alive, wenn auf
Truegesetzt, hält Verbindungen aktiv, indem periodisch Nachrichten gesendet werden.
Geändert in Version 3.13: Der Parameter keep_alive wurde hinzugefügt.
ssl_handshake_timeout ist (für einen TLS-Server) die Zeit in Sekunden, die auf den Abschluss des TLS-Handshakes gewartet wird, bevor die Verbindung abgebrochen wird.
60.0Sekunden, wennNone(Standard).ssl_shutdown_timeout ist die Zeit in Sekunden, die auf den Abschluss des SSL-Shutdowns gewartet wird, bevor die Verbindung abgebrochen wird.
30.0Sekunden, wennNone(Standard).start_serving, wenn auf
True(Standard) gesetzt, bewirkt, dass der erstellte Server sofort mit der Annahme von Verbindungen beginnt. Wenn aufFalsegesetzt, sollte der Benutzer aufServer.start_serving()oderServer.serve_forever()warten, damit der Server mit der Annahme von Verbindungen beginnt.
Geändert in Version 3.5: Unterstützung für SSL/TLS in
ProactorEventLoophinzugefügt.Geändert in Version 3.5.1: Der Parameter host kann eine Sequenz von Strings sein.
Geändert in Version 3.6: Die Parameter ssl_handshake_timeout und start_serving wurden hinzugefügt. Die Socket-Option socket.TCP_NODELAY wird standardmäßig für alle TCP-Verbindungen gesetzt.
Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Siehe auch
Die Funktion
start_server()ist eine höherwertige alternative API, die ein Paar ausStreamReaderundStreamWriterzurückgibt, die in einem async/await-Code verwendet werden können.
- async loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True, cleanup_socket=True)¶
Ähnlich wie
loop.create_server(), arbeitet aber mit derAF_UNIXSocket-Familie.path ist der Name eines Unix-Domain-Sockets und ist erforderlich, es sei denn, ein sock-Argument wird bereitgestellt. Abstrakte Unix-Sockets,
str,bytesundPath-Pfade werden unterstützt.Wenn cleanup_socket wahr ist, wird der Unix-Socket automatisch aus dem Dateisystem entfernt, wenn der Server geschlossen wird, es sei denn, der Socket wurde nach der Erstellung des Servers ersetzt.
Siehe die Dokumentation der Methode
loop.create_server()für Informationen über die Argumente dieser Methode.Verfügbarkeit: Unix.
Geändert in Version 3.7: Die Parameter ssl_handshake_timeout und start_serving wurden hinzugefügt. Der Parameter path kann jetzt ein
Path-Objekt sein.Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Geändert in Version 3.13: Der Parameter cleanup_socket wurde hinzugefügt.
- async loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)¶
Wickelt eine bereits akzeptierte Verbindung in ein Transport-/Protokollpaar ein.
Diese Methode kann von Servern verwendet werden, die Verbindungen außerhalb von asyncio akzeptieren, diese aber mit asyncio verarbeiten.
Parameter
protocol_factory muss ein Callable sein, das eine Protokoll-Implementierung zurückgibt.
sock ist ein bereits vorhandenes Socket-Objekt, das von
socket.acceptzurückgegeben wird.Hinweis
Das Argument sock überträgt das Eigentum am Socket an den erstellten Transport. Um den Socket zu schließen, rufen Sie die Methode
close()des Transports auf.ssl kann auf einen
SSLContextgesetzt werden, um SSL über die akzeptierten Verbindungen zu aktivieren.ssl_handshake_timeout ist (für eine SSL-Verbindung) die Zeit in Sekunden, die auf den Abschluss des SSL-Handshakes gewartet wird, bevor die Verbindung abgebrochen wird.
60.0Sekunden, wennNone(Standard).ssl_shutdown_timeout ist die Zeit in Sekunden, die auf den Abschluss des SSL-Shutdowns gewartet wird, bevor die Verbindung abgebrochen wird.
30.0Sekunden, wennNone(Standard).
Gibt ein
(transport, protocol)-Paar zurück.Hinzugefügt in Version 3.5.3.
Geändert in Version 3.7: Der Parameter ssl_handshake_timeout wurde hinzugefügt.
Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Dateiübertragung¶
- async loop.sendfile(transport, file, offset=0, count=None, *, fallback=True)¶
Sendet eine Datei über einen transport. Gibt die Gesamtzahl der gesendeten Bytes zurück.
Die Methode verwendet das Hochleistungs-
os.sendfile(), falls verfügbar.file muss ein reguläres Dateiobjekt sein, das im Binärmodus geöffnet wurde.
offset gibt an, ab welcher Stelle die Datei gelesen werden soll. Wenn angegeben, ist count die Gesamtzahl der zu übertragenden Bytes, anstatt die Datei bis zum EOF zu senden. Die Dateiposition wird immer aktualisiert, auch wenn diese Methode einen Fehler auslöst, und
file.tell()kann verwendet werden, um die tatsächlich gesendeten Bytes zu ermitteln.fallback auf
Truegesetzt, bewirkt, dass asyncio die Datei manuell liest und sendet, wenn die Plattform den sendfile-Systemaufruf nicht unterstützt (z. B. Windows oder SSL-Socket unter Unix).Löst
SendfileNotAvailableErroraus, wenn das System den sendfile-Syscall nicht unterstützt und fallbackFalseist.Hinzugefügt in Version 3.7.
TLS-Upgrade¶
- async loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)¶
Ein vorhandener Transport-basierter Verbindung auf TLS upgraden.
Erstellt eine TLS-Coder/Decoder-Instanz und fügt sie zwischen den transport und das protocol ein. Der Coder/Decoder implementiert sowohl das transport-seitige Protokoll als auch den protokollseitigen Transport.
Gibt die erstellte Zwei-Interface-Instanz zurück. Nach dem await muss das protocol die ursprüngliche transport nicht mehr verwenden und nur noch mit dem zurückgegebenen Objekt kommunizieren, da der Coder protokollseitige Daten zwischenspeichert und sporadisch zusätzliche TLS-Sitzungspakete mit transport austauscht.
In einigen Situationen (z. B. wenn der übergebene Transport bereits geschlossen wird) kann dies
Nonezurückgeben.Parameter
transport und protocol-Instanzen, die Methoden wie
create_server()undcreate_connection()zurückgeben.sslcontext: eine konfigurierte Instanz von
SSLContext.server_side setzen Sie
True, wenn eine serverseitige Verbindung hochgestuft wird (wie die voncreate_server()erstellte).server_hostname: legt den Hostnamen fest oder überschreibt ihn, gegen den das Zertifikat des Zielservers abgeglichen werden soll.
ssl_handshake_timeout ist (für eine TLS-Verbindung) die Zeit in Sekunden, die auf den Abschluss des TLS-Handshakes gewartet wird, bevor die Verbindung abgebrochen wird.
60.0Sekunden, wennNone(Standard).ssl_shutdown_timeout ist die Zeit in Sekunden, die auf den Abschluss des SSL-Shutdowns gewartet wird, bevor die Verbindung abgebrochen wird.
30.0Sekunden, wennNone(Standard).
Hinzugefügt in Version 3.7.
Geändert in Version 3.11: Der Parameter ssl_shutdown_timeout wurde hinzugefügt.
Überwachung von Dateideskriptoren¶
- loop.add_reader(fd, callback, *args)¶
Beginnt mit der Überwachung des Dateideskriptors fd auf Leseverfügbarkeit und ruft callback mit den angegebenen Argumenten auf, sobald fd zum Lesen verfügbar ist.
Jeder bereits für fd registrierte Callback wird abgebrochen und durch callback ersetzt.
- loop.remove_reader(fd)¶
Beendet die Überwachung des Dateideskriptors fd auf Leseverfügbarkeit. Gibt
Truezurück, wenn fd zuvor für das Lesen überwacht wurde.
- loop.add_writer(fd, callback, *args)¶
Beginnt mit der Überwachung des Dateideskriptors fd auf Schreibverfügbarkeit und ruft callback mit den angegebenen Argumenten auf, sobald fd zum Schreiben verfügbar ist.
Jeder bereits für fd registrierte Callback wird abgebrochen und durch callback ersetzt.
Verwenden Sie
functools.partial()zum Übergeben von Schlüsselwortargumenten an callback.
- loop.remove_writer(fd)¶
Beendet die Überwachung des Dateideskriptors fd auf Schreibverfügbarkeit. Gibt
Truezurück, wenn fd zuvor für das Schreiben überwacht wurde.
Siehe auch den Abschnitt Plattformunterstützung für einige Einschränkungen dieser Methoden.
Arbeiten mit Socket-Objekten direkt¶
Im Allgemeinen sind Protokollimplementierungen, die transportbasierte APIs wie loop.create_connection() und loop.create_server() verwenden, schneller als Implementierungen, die direkt mit Sockets arbeiten. Es gibt jedoch einige Anwendungsfälle, bei denen die Leistung nicht kritisch ist und die Arbeit mit socket-Objekten direkt bequemer ist.
- async loop.sock_recv(sock, nbytes)¶
Empfängt bis zu nbytes von sock. Asynchrone Version von
socket.recv().Gibt die empfangenen Daten als Bytes-Objekt zurück.
sock muss ein nicht-blockierender Socket sein.
Geändert in Version 3.7: Obwohl diese Methode immer als Koroutinenmethode dokumentiert war, gaben Versionen vor Python 3.7 ein
Futurezurück. Seit Python 3.7 ist dies eineasync def-Methode.
- async loop.sock_recv_into(sock, buf)¶
Empfängt Daten von sock in den buf-Puffer. Modelliert nach der blockierenden Methode
socket.recv_into().Gibt die Anzahl der in den Puffer geschriebenen Bytes zurück.
sock muss ein nicht-blockierender Socket sein.
Hinzugefügt in Version 3.7.
- async loop.sock_recvfrom(sock, bufsize)¶
Empfängt ein Datagramm von bis zu bufsize von sock. Asynchrone Version von
socket.recvfrom().Gibt ein Tupel aus (empfangene Daten, entfernte Adresse) zurück.
sock muss ein nicht-blockierender Socket sein.
Hinzugefügt in Version 3.11.
- async loop.sock_recvfrom_into(sock, buf, nbytes=0)¶
Empfängt ein Datagramm von bis zu nbytes von sock in buf. Asynchrone Version von
socket.recvfrom_into().Gibt ein Tupel aus (Anzahl der empfangenen Bytes, entfernte Adresse) zurück.
sock muss ein nicht-blockierender Socket sein.
Hinzugefügt in Version 3.11.
- async loop.sock_sendall(sock, data)¶
Sendet data an den sock-Socket. Asynchrone Version von
socket.sendall().Diese Methode sendet kontinuierlich an den Socket, bis entweder alle Daten in data gesendet wurden oder ein Fehler auftritt. Bei Erfolg wird
Nonezurückgegeben. Bei einem Fehler wird eine Ausnahme ausgelöst. Außerdem gibt es keine Möglichkeit zu ermitteln, wie viele Daten, falls überhaupt, vom empfangenden Ende der Verbindung erfolgreich verarbeitet wurden.sock muss ein nicht-blockierender Socket sein.
Geändert in Version 3.7: Obwohl die Methode immer als Koroutinenmethode dokumentiert war, gaben Versionen vor Python 3.7 ein
Futurezurück. Seit Python 3.7 ist dies eineasync def-Methode.
- async loop.sock_sendto(sock, data, address)¶
Sendet ein Datagramm von sock an address. Asynchrone Version von
socket.sendto().Gibt die Anzahl der gesendeten Bytes zurück.
sock muss ein nicht-blockierender Socket sein.
Hinzugefügt in Version 3.11.
- async loop.sock_connect(sock, address)¶
Verbindet sock mit einem entfernten Socket unter address.
Asynchrone Version von
socket.connect().sock muss ein nicht-blockierender Socket sein.
Geändert in Version 3.5.2: address muss nicht mehr aufgelöst werden.
sock_connectversucht zu prüfen, ob address bereits aufgelöst ist, indemsocket.inet_pton()aufgerufen wird. Wenn nicht, wirdloop.getaddrinfo()verwendet, um address aufzulösen.Siehe auch
- async loop.sock_accept(sock)¶
Akzeptiert eine Verbindung. Modelliert nach der blockierenden Methode
socket.accept().Der Socket muss an eine Adresse gebunden und für Verbindungen offen sein. Der Rückgabewert ist ein Paar
(conn, address), wobei conn ein neues Socket-Objekt ist, das zum Senden und Empfangen von Daten über die Verbindung verwendet werden kann, und address die an den Socket am anderen Ende der Verbindung gebundene Adresse ist.sock muss ein nicht-blockierender Socket sein.
Geändert in Version 3.7: Obwohl die Methode immer als Koroutinenmethode dokumentiert war, gaben Versionen vor Python 3.7 ein
Futurezurück. Seit Python 3.7 ist dies eineasync def-Methode.Siehe auch
- async loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True)¶
Sendet eine Datei mit dem Hochleistungs-
os.sendfile, falls möglich. Gibt die Gesamtzahl der gesendeten Bytes zurück.Asynchrone Version von
socket.sendfile().sock muss ein nicht-blockierender
socket.SOCK_STREAMsocketsein.file muss ein reguläres Dateiobjekt sein, das im Binärmodus geöffnet ist.
offset gibt an, ab welcher Stelle die Datei gelesen werden soll. Wenn angegeben, ist count die Gesamtzahl der zu übertragenden Bytes, anstatt die Datei bis zum EOF zu senden. Die Dateiposition wird immer aktualisiert, auch wenn diese Methode einen Fehler auslöst, und
file.tell()kann verwendet werden, um die tatsächlich gesendeten Bytes zu ermitteln.fallback bewirkt, wenn es auf
Truegesetzt ist, dass asyncio die Datei manuell liest und sendet, wenn die Plattform den sendfile-Systemaufruf nicht unterstützt (z. B. Windows oder SSL-Socket unter Unix).Löst
SendfileNotAvailableErroraus, wenn das System den sendfile-Systemaufruf nicht unterstützt und fallbackFalseist.sock muss ein nicht-blockierender Socket sein.
Hinzugefügt in Version 3.7.
DNS¶
- async loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)¶
Asynchrone Version von
socket.getaddrinfo().
- async loop.getnameinfo(sockaddr, flags=0)¶
Asynchrone Version von
socket.getnameinfo().
Hinweis
Sowohl getaddrinfo als auch getnameinfo nutzen intern ihre synchronen Versionen über den Standard-Threadpool-Executor der Schleife. Wenn dieser Executor gesättigt ist, können diese Methoden Verzögerungen erfahren, die höherstufige Netzwerkbibliotheken als erhöhte Timeouts melden können. Um dies zu mildern, sollten Sie erwägen, einen benutzerdefinierten Executor für andere Benutzertasks zu verwenden oder einen Standard-Executor mit einer größeren Anzahl von Arbeitern einzurichten.
Geändert in Version 3.7: Sowohl die Methoden getaddrinfo als auch getnameinfo gaben immer eine Koroutine zurück, aber vor Python 3.7 gaben sie tatsächlich asyncio.Future-Objekte zurück. Ab Python 3.7 sind beide Methoden Koroutinen.
Arbeiten mit Pipes¶
- async loop.connect_read_pipe(protocol_factory, pipe)¶
Registriert das Leseende von pipe in der Event-Schleife.
protocol_factory muss ein Callable sein, das eine asyncio-Protokoll-Implementierung zurückgibt.
pipe ist ein dateiähnliches Objekt.
Gibt das Paar
(transport, protocol)zurück, wobei transport dieReadTransport-Schnittstelle unterstützt und protocol ein Objekt ist, das von protocol_factory instanziiert wurde.Mit der
SelectorEventLoopEreignisschleife wird die Pipe in den nicht-blockierenden Modus versetzt.
- async loop.connect_write_pipe(protocol_factory, pipe)¶
Registriert das Schreibende von pipe in der Ereignisschleife.
protocol_factory muss ein Callable sein, das eine asyncio-Protokoll-Implementierung zurückgibt.
pipe ist ein dateiähnliches Objekt.
Gibt ein Paar
(transport, protocol)zurück, wobei transport dieWriteTransportSchnittstelle unterstützt und protocol ein von protocol_factory instanziiertes Objekt ist.Mit der
SelectorEventLoopEreignisschleife wird die Pipe in den nicht-blockierenden Modus versetzt.
Hinweis
SelectorEventLoop unterstützt die obigen Methoden unter Windows nicht. Verwenden Sie stattdessen ProactorEventLoop für Windows.
Siehe auch
Die Methoden loop.subprocess_exec() und loop.subprocess_shell().
Unix-Signale¶
- loop.add_signal_handler(signum, callback, *args)¶
Setzt callback als Handler für das signum Signal.
Der Callback wird von loop aufgerufen, zusammen mit anderen wartenden Callbacks und ausführbaren Coroutinen dieser Ereignisschleife. Im Gegensatz zu Signal-Handlern, die über
signal.signal()registriert werden, darf ein mit dieser Funktion registrierter Callback mit der Ereignisschleife interagieren.Löst
ValueErroraus, wenn die Signalnummer ungültig oder nicht abfangbar ist. LöstRuntimeErroraus, wenn ein Problem beim Einrichten des Handlers auftritt.Verwenden Sie
functools.partial()zum Übergeben von Schlüsselwortargumenten an callback.Wie
signal.signal()muss diese Funktion im Hauptthread aufgerufen werden.
- loop.remove_signal_handler(sig)¶
Entfernt den Handler für das sig Signal.
Gibt
Truezurück, wenn der Signal-Handler entfernt wurde, oderFalse, wenn kein Handler für das gegebene Signal gesetzt war.Verfügbarkeit: Unix.
Siehe auch
Das Modul signal.
Ausführung von Code in Thread- oder Prozesspools¶
- awaitable loop.run_in_executor(executor, func, *args)¶
Veranlasst, dass func im angegebenen Executor aufgerufen wird.
Das Argument executor sollte eine Instanz von
concurrent.futures.Executorsein. Der Standard-Executor wird verwendet, wenn executorNoneist. Der Standard-Executor kann durchloop.set_default_executor()gesetzt werden, andernfalls wird einconcurrent.futures.ThreadPoolExecutorlazy-initialisiert und bei Bedarf vonrun_in_executor()verwendet.Beispiel
import asyncio import concurrent.futures def blocking_io(): # File operations (such as logging) can block the # event loop: run them in a thread pool. with open('/dev/urandom', 'rb') as f: return f.read(100) def cpu_bound(): # CPU-bound operations will block the event loop: # in general it is preferable to run them in a # process pool. return sum(i * i for i in range(10 ** 7)) async def main(): loop = asyncio.get_running_loop() ## Options: # 1. Run in the default loop's executor: result = await loop.run_in_executor( None, blocking_io) print('default thread pool', result) # 2. Run in a custom thread pool: with concurrent.futures.ThreadPoolExecutor() as pool: result = await loop.run_in_executor( pool, blocking_io) print('custom thread pool', result) # 3. Run in a custom process pool: with concurrent.futures.ProcessPoolExecutor() as pool: result = await loop.run_in_executor( pool, cpu_bound) print('custom process pool', result) # 4. Run in a custom interpreter pool: with concurrent.futures.InterpreterPoolExecutor() as pool: result = await loop.run_in_executor( pool, cpu_bound) print('custom interpreter pool', result) if __name__ == '__main__': asyncio.run(main())
Beachten Sie, dass die Einstiegspunkt-Guard (
if __name__ == '__main__') für Option 3 aufgrund der Besonderheiten vonmultiprocessingerforderlich ist, das vonProcessPoolExecutorverwendet wird. Siehe Sicheres Importieren des Hauptmoduls.Diese Methode gibt ein
asyncio.FutureObjekt zurück.Verwenden Sie
functools.partial()um Schlüsselwortargumente an func zu übergeben.Geändert in Version 3.5.3:
loop.run_in_executor()konfiguriert diemax_workersdes von ihm erstellten Thread-Pool-Executors nicht mehr, sondern überlässt es dem Thread-Pool-Executor (ThreadPoolExecutor), den Standardwert festzulegen.
- loop.set_default_executor(executor)¶
Setzt executor als Standard-Executor, der von
run_in_executor()verwendet wird. executor muss eine Instanz vonThreadPoolExecutorsein, wasInterpreterPoolExecutoreinschließt.Geändert in Version 3.11: executor muss eine Instanz von
ThreadPoolExecutorsein.
API zur Fehlerbehandlung¶
Ermöglicht die Anpassung der Behandlung von Ausnahmen in der Ereignisschleife.
- loop.set_exception_handler(handler)¶
Setzt handler als neuen Ausnahmekoordinator der Ereignisschleife.
Wenn handler
Noneist, wird der Standard-Ausnahmekoordinator gesetzt. Andernfalls muss handler ein aufrufbares Objekt sein, dessen Signatur mit(loop, context)übereinstimmt, wobeiloopein Verweis auf die aktive Ereignisschleife ist undcontexteindict-Objekt ist, das die Details der Ausnahme enthält (siehe Dokumentation zucall_exception_handler()für Details zum Kontext).Wenn der Handler im Auftrag eines
TaskoderHandleaufgerufen wird, wird er imcontextvars.Contextdieses Tasks oder Callback-Handles ausgeführt.Geändert in Version 3.12: Der Handler kann im
Contextdes Tasks oder Handles, aus dem die Ausnahme stammt, aufgerufen werden.
- loop.get_exception_handler()¶
Gibt den aktuellen Ausnahmekoordinator zurück oder
None, wenn kein benutzerdefinierter Ausnahmekoordinator gesetzt wurde.Hinzugefügt in Version 3.5.2.
- loop.default_exception_handler(context)¶
Standard-Ausnahmekoordinator.
Dies wird aufgerufen, wenn eine Ausnahme auftritt und kein Ausnahmekoordinator gesetzt ist. Dies kann von einem benutzerdefinierten Ausnahmekoordinator aufgerufen werden, der das Standardverhalten des Koordinators beibehalten möchte.
Der Parameter context hat die gleiche Bedeutung wie in
call_exception_handler().
- loop.call_exception_handler(context)¶
Ruft den aktuellen Ausnahmekoordinator der Ereignisschleife auf.
context ist ein
dict-Objekt, das die folgenden Schlüssel enthält (in zukünftigen Python-Versionen können weitere Schlüssel hinzugefügt werden)‘message’: Fehlermeldung;
‘exception’ (optional): Ausnahmeobjekt;
‘future’ (optional):
asyncio.FutureInstanz;‘task’ (optional):
asyncio.TaskInstanz;‘handle’ (optional):
asyncio.HandleInstanz;‘protocol’ (optional): Protokoll Instanz;
‘transport’ (optional): Transport Instanz;
‘socket’ (optional):
socket.socketInstanz;‘source_traceback’ (optional): Traceback der Quelle;
‘handle_traceback’ (optional): Traceback des Handles;
- ‘asyncgen’ (optional): Asynchroner Generator, der die
Ausnahme verursacht hat.
Hinweis
Diese Methode sollte in abgeleiteten Ereignisschleifen nicht überschrieben werden. Verwenden Sie für benutzerdefinierte Ausnahmebehandlung die Methode
set_exception_handler().
Aktivieren des Debug-Modus¶
- loop.get_debug()¶
Ruft den Debug-Modus (
bool) der Ereignisschleife ab.Der Standardwert ist
True, wenn die UmgebungsvariablePYTHONASYNCIODEBUGauf eine nicht-leere Zeichenkette gesetzt ist, andernfallsFalse.
- loop.set_debug(enabled: bool)¶
Setzt den Debug-Modus der Ereignisschleife.
Geändert in Version 3.7: Der neue Python-Entwicklermodus kann auch verwendet werden, um den Debug-Modus zu aktivieren.
- loop.slow_callback_duration¶
Dieses Attribut kann verwendet werden, um die minimale Ausführungsdauer in Sekunden festzulegen, die als "langsam" gilt. Wenn der Debug-Modus aktiviert ist, werden "langsame" Callbacks protokolliert.
Standardwert ist 100 Millisekunden.
Siehe auch
Ausführung von Subprozessen¶
Die in diesem Unterabschnitt beschriebenen Methoden sind Low-Level. In normalem Async/Await-Code sollten stattdessen die High-Level-Komfortfunktionen asyncio.create_subprocess_shell() und asyncio.create_subprocess_exec() verwendet werden.
Hinweis
Unter Windows unterstützt die Standard-Ereignisschleife ProactorEventLoop Subprozesse, während SelectorEventLoop dies nicht tut. Siehe Unterstützung für Subprozesse unter Windows für Details.
- async loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)¶
Erstellt einen Subprozess aus einem oder mehreren Zeichenkettenargumenten, die durch args angegeben werden.
args muss eine Liste von Zeichenketten sein, dargestellt durch
str;oder
bytes, kodiert auf die Dateisystemkodierung.
Die erste Zeichenkette gibt das Programm-Executable an, die restlichen Zeichenketten die Argumente. Zusammen bilden die Zeichenkettenargumente die
argvdes Programms.Dies ähnelt der Standardbibliotheksklasse
subprocess.Popen, aufgerufen mitshell=Falseund der Zeichenkettenliste als erstem Argument; wobeiPopenein einzelnes Argument erwartet, das eine Liste von Zeichenketten ist, nimmt subprocess_exec mehrere Zeichenkettenargumente.protocol_factory muss ein aufrufbares Objekt sein, das eine Unterklasse der Klasse
asyncio.SubprocessProtocolzurückgibt.Andere Parameter
stdin kann eines der folgenden sein:
ein dateiähnliches Objekt
ein bestehender Dateideskriptor (eine positive Ganzzahl), z. B. erzeugt mit
os.pipe()die Konstante
subprocess.PIPE(Standard), die eine neue Pipe erstellt und sie verbindet,der Wert
None, der dazu führt, dass der Subprozess den Dateideskriptor von diesem Prozess erbtdie Konstante
subprocess.DEVNULL, die angibt, dass die spezielle Dateios.devnullverwendet wird
stdout kann eines der folgenden sein:
ein dateiähnliches Objekt
die Konstante
subprocess.PIPE(Standard), die eine neue Pipe erstellt und sie verbindet,der Wert
None, der dazu führt, dass der Subprozess den Dateideskriptor von diesem Prozess erbtdie Konstante
subprocess.DEVNULL, die angibt, dass die spezielle Dateios.devnullverwendet wird
stderr kann eines der folgenden sein:
ein dateiähnliches Objekt
die Konstante
subprocess.PIPE(Standard), die eine neue Pipe erstellt und sie verbindet,der Wert
None, der dazu führt, dass der Subprozess den Dateideskriptor von diesem Prozess erbtdie Konstante
subprocess.DEVNULL, die angibt, dass die spezielle Dateios.devnullverwendet wirddie Konstante
subprocess.STDOUT, die den Standardfehlerstrom mit dem Standardausgabestrom des Prozesses verbindet
Alle anderen Schlüsselwortargumente werden ohne Interpretation an
subprocess.Popenübergeben, mit Ausnahme von bufsize, universal_newlines, shell, text, encoding und errors, die überhaupt nicht angegeben werden sollten.Die
asyncioSubprozess-API unterstützt nicht das Dekodieren von Streams als Text.bytes.decode()kann verwendet werden, um die von den Streams zurückgegebenen Bytes in Text umzuwandeln.
Wenn ein dateiähnliches Objekt, das als stdin, stdout oder stderr übergeben wird, eine Pipe repräsentiert, dann sollte die andere Seite dieser Pipe mit
connect_write_pipe()oderconnect_read_pipe()für die Verwendung mit der Ereignisschleife registriert werden.Siehe den Konstruktor der Klasse
subprocess.Popenfür Dokumentation zu anderen Argumenten.Gibt ein Paar von
(transport, protocol)zurück, wobei transport der Basisklasseasyncio.SubprocessTransportentspricht und protocol ein von protocol_factory instanziiertes Objekt ist.
- async loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)¶
Erstellt einen Subprozess aus cmd, bei dem es sich um eine
stroder einebytesZeichenkette handeln kann, die auf die Dateisystemkodierung kodiert ist, unter Verwendung der "Shell"-Syntax der Plattform.Dies ähnelt der Standardbibliotheksklasse
subprocess.Popen, aufgerufen mitshell=True.protocol_factory muss ein aufrufbares Objekt sein, das eine Unterklasse der Klasse
SubprocessProtocolzurückgibt.Siehe
subprocess_exec()für weitere Details zu den übrigen Argumenten.Gibt ein Paar von
(transport, protocol)zurück, wobei transport der KlasseSubprocessTransportentspricht und protocol ein von protocol_factory instanziiertes Objekt ist.
Hinweis
Es liegt in der Verantwortung der Anwendung, sicherzustellen, dass alle Leerzeichen und Sonderzeichen ordnungsgemäß maskiert werden, um Shell-Injection-Schwachstellen zu vermeiden. Die Funktion shlex.quote() kann verwendet werden, um Leerzeichen und Sonderzeichen in Zeichenketten, die zur Erstellung von Shell-Befehlen verwendet werden sollen, korrekt zu maskieren.
Callback-Handles¶
- class asyncio.Handle¶
Ein Callback-Wrapper-Objekt, das von
loop.call_soon(),loop.call_soon_threadsafe()zurückgegeben wird.- get_context()¶
Gibt das dem Handle zugeordnete
contextvars.ContextObjekt zurück.Hinzugefügt in Version 3.12.
- cancel()¶
Bricht den Callback ab. Wenn der Callback bereits abgebrochen oder ausgeführt wurde, hat diese Methode keine Auswirkung.
- cancelled()¶
Gibt
Truezurück, wenn der Callback abgebrochen wurde.Hinzugefügt in Version 3.7.
- class asyncio.TimerHandle¶
Ein Callback-Wrapper-Objekt, das von
loop.call_later()undloop.call_at()zurückgegeben wird.Diese Klasse ist eine Unterklasse von
Handle.- when()¶
Gibt die geplante Callback-Zeit als
floatSekunden zurück.Die Zeit ist ein absoluter Zeitstempel, der dieselbe Zeitreferenz wie
loop.time()verwendet.Hinzugefügt in Version 3.7.
Server-Objekte¶
Server-Objekte werden von den Funktionen loop.create_server(), loop.create_unix_server(), start_server() und start_unix_server() erstellt.
Instanziieren Sie die Klasse Server nicht direkt.
- class asyncio.Server¶
Server-Objekte sind asynchrone Kontextmanager. Wenn sie in einer
async with-Anweisung verwendet werden, ist garantiert, dass das Server-Objekt geschlossen wird und keine neuen Verbindungen akzeptiert, wenn dieasync with-Anweisung abgeschlossen istsrv = await loop.create_server(...) async with srv: # some code # At this point, srv is closed and no longer accepts new connections.
Geändert in Version 3.7: Server-Objekt ist seit Python 3.7 ein asynchroner Kontextmanager.
Geändert in Version 3.11: Diese Klasse wurde in Python 3.9.11, 3.10.3 und 3.11 öffentlich als
asyncio.Serverexponiert.- close()¶
Beenden des Dienstes: Schließen der Listening-Sockets und Setzen des
sockets-Attributs aufNone.Die Sockets, die bestehende eingehende Client-Verbindungen repräsentieren, bleiben geöffnet.
Der Server wird asynchron geschlossen; verwenden Sie die
wait_closed()Coroutine, um zu warten, bis der Server geschlossen ist (und keine Verbindungen mehr aktiv sind).
- close_clients()¶
Schließen Sie alle bestehenden eingehenden Client-Verbindungen.
Ruft
close()auf allen zugehörigen Transports auf.Vor dem Schließen des Servers sollte
close()vorclose_clients()aufgerufen werden, um Wettlaufsituationen mit neu verbundenen Clients zu vermeiden.Hinzugefügt in Version 3.13.
- abort_clients()¶
Schließen Sie alle bestehenden eingehenden Client-Verbindungen sofort ab, ohne auf den Abschluss ausstehender Operationen zu warten.
Ruft
abort()auf allen zugehörigen Transports auf.Vor dem Schließen des Servers sollte
close()vorabort_clients()aufgerufen werden, um Wettlaufsituationen mit neu verbundenen Clients zu vermeiden.Hinzugefügt in Version 3.13.
- get_loop()¶
Gibt die dem Server-Objekt zugeordnete Ereignisschleife zurück.
Hinzugefügt in Version 3.7.
- async start_serving()¶
Beginnen Sie mit dem Akzeptieren von Verbindungen.
Diese Methode ist idempotent, kann also aufgerufen werden, wenn der Server bereits bedient.
Der Schlüsselwortparameter _start_serving_ für
loop.create_server()undasyncio.start_server()ermöglicht die Erstellung eines Server-Objekts, das anfangs keine Verbindungen akzeptiert. In diesem Fall kannServer.start_serving()oderServer.serve_forever()verwendet werden, um den Server mit dem Akzeptieren von Verbindungen zu beginnen.Hinzugefügt in Version 3.7.
- async serve_forever()¶
Beginnen Sie mit dem Akzeptieren von Verbindungen, bis die Coroutine abgebrochen wird. Ein Abbruch der
serve_foreverAufgabe führt zum Schließen des Servers.Diese Methode kann aufgerufen werden, wenn der Server bereits Verbindungen akzeptiert. Pro Server-Objekt kann nur eine
serve_foreverAufgabe existieren.Beispiel
async def client_connected(reader, writer): # Communicate with the client with # reader/writer streams. For example: await reader.readline() async def main(host, port): srv = await asyncio.start_server( client_connected, host, port) await srv.serve_forever() asyncio.run(main('127.0.0.1', 0))
Hinzugefügt in Version 3.7.
- is_serving()¶
Gibt
Truezurück, wenn der Server neue Verbindungen akzeptiert.Hinzugefügt in Version 3.7.
- async wait_closed()¶
Warten Sie, bis die Methode
close()abgeschlossen ist und alle aktiven Verbindungen beendet sind.
- sockets¶
Liste von Socket-ähnlichen Objekten,
asyncio.trsock.TransportSocket, auf denen der Server lauscht.Geändert in Version 3.7: Vor Python 3.7 gab
Server.socketseine interne Liste von Server-Sockets direkt zurück. In 3.7 wird eine Kopie dieser Liste zurückgegeben.
Implementierungen der Ereignisschleife¶
asyncio wird mit zwei verschiedenen Implementierungen der Ereignisschleife geliefert: SelectorEventLoop und ProactorEventLoop.
Standardmäßig ist asyncio so konfiguriert, dass es EventLoop verwendet.
- class asyncio.SelectorEventLoop¶
Eine Unterklasse von
AbstractEventLoop, die auf dem Modulselectorsbasiert.Verwendet den effizientesten für die gegebene Plattform verfügbaren Selektor. Es ist auch möglich, die genaue zu verwendende Selektorimplementierung manuell zu konfigurieren.
import asyncio import selectors async def main(): ... loop_factory = lambda: asyncio.SelectorEventLoop(selectors.SelectSelector()) asyncio.run(main(), loop_factory=loop_factory)
Verfügbarkeit: Unix, Windows.
- class asyncio.ProactorEventLoop¶
Eine Unterklasse von
AbstractEventLoopfür Windows, die "I/O Completion Ports" (IOCP) verwendet.Verfügbarkeit: Windows.
Siehe auch
- class asyncio.EventLoop¶
Ein Alias für die für die gegebene Plattform effizienteste verfügbare Unterklasse von
AbstractEventLoop.Es ist ein Alias für
SelectorEventLoopunter Unix undProactorEventLoopunter Windows.Hinzugefügt in Version 3.13.
- class asyncio.AbstractEventLoop¶
Abstrakte Basisklasse für asyncio-konforme Ereignisschleifen.
Der Abschnitt Event Loop-Methoden listet alle Methoden auf, die eine alternative Implementierung von
AbstractEventLoopdefinieren sollte.
Beispiele¶
Beachten Sie, dass alle Beispiele in diesem Abschnitt **absichtlich** zeigen, wie die Low-Level-Ereignisschleifen-APIs wie loop.run_forever() und loop.call_soon() verwendet werden. Moderne asyncio-Anwendungen müssen selten auf diese Weise geschrieben werden; erwägen Sie die Verwendung der High-Level-Funktionen wie asyncio.run().
Hallo Welt mit call_soon()¶
Ein Beispiel, das die Methode loop.call_soon() verwendet, um einen Callback zu planen. Der Callback zeigt "Hello World" an und stoppt dann die Ereignisschleife.
import asyncio
def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
Siehe auch
Ein ähnliches Hallo Welt-Beispiel, das mit einer Coroutine und der Funktion run() erstellt wurde.
Zeige das aktuelle Datum mit call_later()¶
Ein Beispiel für einen Callback, der jede Sekunde das aktuelle Datum anzeigt. Der Callback verwendet die Methode loop.call_later(), um sich nach 5 Sekunden neu zu planen und stoppt dann die Ereignisschleife.
import asyncio
import datetime
def display_date(end_time, loop):
print(datetime.datetime.now())
if (loop.time() + 1.0) < end_time:
loop.call_later(1, display_date, end_time, loop)
else:
loop.stop()
loop = asyncio.new_event_loop()
# Schedule the first call to display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
Siehe auch
Ein ähnliches aktuelles Datum-Beispiel, das mit einer Coroutine und der Funktion run() erstellt wurde.
Überwachen eines Dateideskriptors auf Lesereignisse¶
Warten, bis ein Dateideskriptor Daten empfangen hat, mithilfe der Methode loop.add_reader(), und dann die Ereignisschleife schließen.
import asyncio
from socket import socketpair
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
loop = asyncio.new_event_loop()
def reader():
data = rsock.recv(100)
print("Received:", data.decode())
# We are done: unregister the file descriptor
loop.remove_reader(rsock)
# Stop the event loop
loop.stop()
# Register the file descriptor for read event
loop.add_reader(rsock, reader)
# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())
try:
# Run the event loop
loop.run_forever()
finally:
# We are done. Close sockets and the event loop.
rsock.close()
wsock.close()
loop.close()
Siehe auch
Ein ähnliches Beispiel, das Transports, Protokolle und die Methode
loop.create_connection()verwendet.Ein weiteres ähnliches Beispiel, das die High-Level-Funktion
asyncio.open_connection()und Streams verwendet.
Setzen von Signal-Handlern für SIGINT und SIGTERM¶
(Dieses signals-Beispiel funktioniert nur unter Unix.)
Registrieren von Handlern für die Signale SIGINT und SIGTERM mit der Methode loop.add_signal_handler().
import asyncio
import functools
import os
import signal
def ask_exit(signame, loop):
print("got signal %s: exit" % signame)
loop.stop()
async def main():
loop = asyncio.get_running_loop()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(
getattr(signal, signame),
functools.partial(ask_exit, signame, loop))
await asyncio.sleep(3600)
print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")
asyncio.run(main())