select — auf Ereignisse auf einer Menge von Streams warten¶
Dieses Modul stellt Funktionen bereit, um effizient zu warten, bis einer oder mehrere streams (dateiähnliche Objekte, die das Stream-Protokoll implementieren, wie Sockets, UARTs und andere I/O-Objekte) zum Lesen oder Schreiben bereit ist, anstatt aktiv abzuwarten (Busy-Waiting) oder auf einem einzelnen Objekt zu blockieren.
Das poll-Objekt ist die empfohlene Schnittstelle: Es skaliert auf viele Streams und ist allokationsfrei, wenn es über poll.ipoll() verwendet wird. Die Funktion select() auf Modulebene ist eine weniger effiziente Kompatibilitätsschnittstelle.
Beispiel mit einem poll-Objekt:
import select
poller = select.poll()
poller.register(uart, select.POLLIN)
while True:
# Wait up to 1000 ms for the UART to have data.
for obj, event in poller.poll(1000):
if event & select.POLLIN:
print(obj.read())
Beispiel mit der select()-Funktion auf Modulebene:
import select
# Wait up to 1 second for the socket to become readable.
rlist, wlist, xlist = select.select([sock], [], [], 1.0)
if rlist:
data = sock.recv(100)
Funktionen¶
- select.select(rlist: List, wlist: List, xlist: List, timeout: float | None = None) Tuple[List, List, List]¶
Wartet, bis eines oder mehrere der angegebenen Stream-Objekte bereit ist, oder bis timeout abläuft.
rlist ist eine Liste von Objekten, die auf Lesbarkeit überwacht werden sollen.
wlist ist eine Liste von Objekten, die auf Schreibbarkeit überwacht werden sollen.
xlist ist eine Liste von Objekten, die auf eine Fehler- oder Verbindungsabbruchbedingung überwacht werden sollen.
timeout ist die maximale Wartezeit in Sekunden (ein Float wird akzeptiert). Wenn es weggelassen wird oder
Noneist, blockiert der Aufruf unbegrenzt;0kehrt sofort zurück (ein nicht blockierendes Poll).
Gibt ein 3-Tupel von Listen
(rlist, wlist, xlist)zurück. Jede zurückgegebene Liste ist die Teilmenge der entsprechenden Eingabeliste, die jeweils die Objekte enthält, die zum Lesen bereit wurden, zum Schreiben bereit wurden oder einen Fehler bzw. Verbindungsabbruch signalisiert haben. Wenn timeout abläuft, ohne dass etwas bereit ist, sind alle drei Listen leer.Diese Funktion ist weniger effizient als
poll(sie baut bei jedem Aufruf ihre interne Poll-Menge neu auf); verwenden Sie nach Möglichkeit stattdessenpoll.
Konstanten¶
- select.POLLERR: int¶
Eine Fehlerbedingung ist auf dem Stream aufgetreten. Dies ist ein unaufgefordertes Ereignis: Es wird von
poll.poll()/poll.ipoll()gemeldet, auch wenn es nicht in der eventmask angefordert wurde, und es ist nicht gültig, es als Eingabe-eventmask zu übergeben.
- select.POLLHUP: int¶
Der Stream wurde aufgelegt / getrennt. Dies ist ein unaufgefordertes Ereignis: Es wird von
poll.poll()/poll.ipoll()gemeldet, auch wenn es nicht in der eventmask angefordert wurde, und es ist nicht gültig, es als Eingabe-eventmask zu übergeben.
Klassen¶
- class select.poll¶
Erstellt ein Polling-Objekt, das eine Menge registrierter Streams (oder beliebiger Objekte, die das Stream-Protokoll bereitstellen) verwaltet und effizient wartet, bis einer oder mehrere von ihnen lesbar oder schreibbar werden oder eine Ausnahmebedingung signalisieren.
Streams werden mit
register()hinzugefügt, mitunregister()entfernt, und die Menge der zu überwachenden Ereignisse kann mitmodify()geändert werden. Sobald konfiguriert, rufen Siepoll()auf, um zu blockieren, bis etwas bereit ist (oder ein Timeout abläuft), oderipoll()für eine allokationsfreie, iteratorbasierte Variante.- register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None¶
Registriert den stream obj für das Polling und überwacht die durch eventmask angegebenen Ereignisse (die logische ODER-Verknüpfung von):
select.POLLIN– Daten stehen zum Lesen zur Verfügungselect.POLLOUT– der Stream kann weitere zu schreibende Daten aufnehmen
eventmask ist standardmäßig
select.POLLIN | select.POLLOUT.select.POLLHUPundselect.POLLERRsind in einer Eingabe-eventmask nicht gültig – es handelt sich um unaufgeforderte Ereignisse, die vonpoll()/ipoll()gemeldet werden, unabhängig davon, ob sie angefordert wurden (dies entspricht der POSIX-Semantik).Es ist in Ordnung, diese Methode mehr als einmal für dasselbe obj aufzurufen: Ein nachfolgender Aufruf aktualisiert die Ereignismaske von obj und verhält sich wie
modify().
- unregister(obj: Any) None¶
Entfernt obj aus der Menge der registrierten Streams. Es ist kein Fehler, ein obj zu deregistrieren, das aktuell nicht registriert ist (der Aufruf hat in diesem Fall keine Wirkung).
- modify(obj: Any, eventmask: int) None¶
Ändert die Ereignismaske für ein bereits registriertes obj auf eventmask. Löst
OSErrormiterrno.ENOENTaus, falls obj nicht registriert ist.
- poll(timeout: int = -1, /) List[Tuple]¶
Blockiert, bis mindestens ein registrierter Stream bereit wird oder eine Ausnahmebedingung signalisiert, und gibt dann die Liste der Streams zurück, die ausgelöst haben.
timeout ist die maximale Wartezeit in Millisekunden. Wenn es weggelassen wird oder
-1ist, blockiert der Aufruf unbegrenzt;0kehrt sofort zurück (ein nicht blockierendes Poll).Gibt eine Liste von
(obj, event, ...)-Tupeln zurück, eines pro Stream, der ausgelöst hat.objist der registrierte Stream undeventist die bitweise ODER-Verknüpfung der aufgetretenen Flagsselect.POLLIN/select.POLLOUT/select.POLLERR/select.POLLHUP. Jedes Tupel kann zusätzliche implementierungsdefinierte Elemente enthalten, gehen Sie also nicht von einer Länge von genau 2 aus. Wenn timeout abläuft, ohne dass etwas bereit ist, wird eine leere Liste zurückgegeben.select.POLLHUPundselect.POLLERRkönnen jederzeit zurückgegeben werden (auch wenn nicht angefordert) und müssen behandelt werden – typischerweise durch Deregistrieren und Schließen des betroffenen Streams – andernfalls kehren nachfolgende Aufrufe weiterhin sofort zurück, wobei diese Flags für diesen Stream gesetzt sind.Es ist garantiert, dass alle ausstehenden geplanten Callbacks ausgeführt werden, bevor die Polling-Schleife betreten wird.
Unterschied zu CPython
Zurückgegebene Tupel können mehr als 2 Elemente enthalten, wie oben beschrieben.
- ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]¶
Wie
poll(), aber anstatt eine Liste aufzubauen, wird ein Iterator zurückgegeben, der jeweils ein(obj, event, ...)-Tupel liefert. Dies vermeidet eine Allokation bei jedem Aufruf, was für asynchrone I/O-Scheduler wichtig ist.Das gelieferte Tupel ist callee-owned: Es wird bei der nächsten Iteration wiederverwendet (überschrieben), daher muss sein Inhalt innerhalb des Schleifenkörpers verarbeitet werden, und Referenzen darauf dürfen nicht gespeichert werden.
timeout hat dieselbe Bedeutung wie bei
poll(). Wenn flags1ist, wird One-Shot-Verhalten verwendet: Bei einem Stream, dessen Ereignis ausgelöst hat, wird seine Ereignismaske automatisch gelöscht (entsprichtpoll.modify(obj, 0)), sodass keine weiteren Ereignisse für ihn gemeldet werden, bis seine Maske mitmodify()erneut gesetzt wird.Es ist garantiert, dass alle ausstehenden geplanten Callbacks ausgeführt werden, bevor die Polling-Schleife betreten wird.
Unterschied zu CPython
Diese Methode ist eine MicroPython-Erweiterung.