selectors — High-level I/O multiplexing

Hinzugefügt in Version 3.4.

Quellcode: Lib/selectors.py


Einleitung

Dieses Modul ermöglicht High-Level und effizientes I/O-Multiplexing, das auf den select Modul-Primitiven aufbaut. Benutzer werden ermutigt, dieses Modul stattdessen zu verwenden, es sei denn, sie möchten präzise Kontrolle über die verwendeten OS-Level-Primitiven haben.

Es definiert eine BaseSelector abstrakte Basisklasse, zusammen mit mehreren konkreten Implementierungen (KqueueSelector, EpollSelector…), die verwendet werden können, um auf I/O-Bereitschaftsbenachrichtigungen auf mehreren Datei-Objekten zu warten. Im Folgenden bezieht sich "Datei-Objekt" auf jedes Objekt mit einer fileno() Methode oder einem rohen Dateideskriptor. Siehe Datei-Objekt.

DefaultSelector ist ein Alias für die effizienteste auf der aktuellen Plattform verfügbare Implementierung: dies sollte die Standardwahl für die meisten Benutzer sein.

Hinweis

Der Typ der unterstützten Datei-Objekte hängt von der Plattform ab: unter Windows werden Sockets unterstützt, aber keine Pipes, während unter Unix beide unterstützt werden (einige andere Typen können ebenfalls unterstützt werden, wie Fifos oder spezielle Gerätedateien).

Siehe auch

select

Low-Level I/O-Multiplexing-Modul.

Verfügbarkeit: nicht WASI.

Dieses Modul funktioniert nicht oder ist nicht auf WebAssembly verfügbar. Weitere Informationen finden Sie unter WebAssembly-Plattformen.

Klassen

Klassenhierarchie

BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector

Im Folgenden ist *events* eine bitweise Maske, die angibt, auf welche I/O-Ereignisse auf einem gegebenen Datei-Objekt gewartet werden soll. Sie kann eine Kombination der folgenden Modulkonstanten sein.

Konstante

Bedeutung

selectors.EVENT_READ

Für das Lesen verfügbar

selectors.EVENT_WRITE

Für das Schreiben verfügbar

class selectors.SelectorKey

Ein SelectorKey ist ein namedtuple, das verwendet wird, um ein Datei-Objekt mit seinem zugrunde liegenden Dateideskriptor, der ausgewählten Ereignismaske und angehängten Daten zu verknüpfen. Es wird von mehreren BaseSelector Methoden zurückgegeben.

fileobj

Registriertes Datei-Objekt.

fd

Zugrunde liegender Dateideskriptor.

events

Ereignisse, auf die bei diesem Datei-Objekt gewartet werden muss.

data

Optionale, undurchsichtige Daten, die diesem Datei-Objekt zugeordnet sind: zum Beispiel könnten sie verwendet werden, um eine pro Client-Sitzungs-ID zu speichern.

class selectors.BaseSelector

Ein BaseSelector wird verwendet, um auf I/O-Ereignisbereitschaft auf mehreren Datei-Objekten zu warten. Er unterstützt die Registrierung, Deregistrierung von Dateiströmen und eine Methode zum Warten auf I/O-Ereignisse auf diesen Strömen mit einem optionalen Timeout. Es handelt sich um eine abstrakte Basisklasse und kann daher nicht instanziiert werden. Verwenden Sie stattdessen DefaultSelector oder eine der Klassen SelectSelector, KqueueSelector usw., wenn Sie speziell eine Implementierung verwenden möchten und Ihre Plattform dies unterstützt. BaseSelector und seine konkreten Implementierungen unterstützen das Protokoll für Kontextmanager.

abstractmethod register(fileobj, events, data=None)

Registriert ein Datei-Objekt zur Auswahl und überwacht es auf I/O-Ereignisse.

fileobj ist das zu überwachende Datei-Objekt. Es kann entweder ein Integer-Dateideskriptor oder ein Objekt mit einer fileno()-Methode sein. events ist eine bitweise Maske der zu überwachenden Ereignisse. data ist ein undurchsichtiges Objekt.

Dies gibt eine neue SelectorKey-Instanz zurück oder löst im Falle einer ungültigen Ereignismaske oder eines ungültigen Dateideskriptors eine ValueError aus, oder eine KeyError, wenn das Datei-Objekt bereits registriert ist.

abstractmethod unregister(fileobj)

Hebt die Registrierung eines Datei-Objekts von der Auswahl auf und entfernt es aus der Überwachung. Ein Datei-Objekt muss deregistriert werden, bevor es geschlossen wird.

fileobj muss ein zuvor registriertes Datei-Objekt sein.

Dies gibt die zugehörige SelectorKey-Instanz zurück oder löst eine KeyError aus, wenn fileobj nicht registriert ist. Es wird eine ValueError ausgelöst, wenn fileobj ungültig ist (z. B. wenn es keine fileno()-Methode hat oder seine fileno()-Methode einen ungültigen Rückgabewert hat).

modify(fileobj, events, data=None)

Ändert die überwachten Ereignisse oder angehängten Daten eines registrierten Datei-Objekts.

Dies ist äquivalent zu BaseSelector.unregister(fileobj) gefolgt von BaseSelector.register(fileobj, events, data), außer dass es effizienter implementiert werden kann.

Dies gibt eine neue SelectorKey-Instanz zurück oder löst im Falle einer ungültigen Ereignismaske oder eines ungültigen Dateideskriptors eine ValueError aus, oder eine KeyError, wenn das Datei-Objekt nicht registriert ist.

abstractmethod select(timeout=None)

Wartet, bis einige registrierte Datei-Objekte bereit werden oder der Timeout abläuft.

Wenn timeout > 0, gibt dies die maximale Wartezeit in Sekunden an. Wenn timeout <= 0, wird der Aufruf nicht blockieren und die derzeit bereiten Datei-Objekte melden. Wenn timeout None ist, blockiert der Aufruf, bis ein überwachtes Datei-Objekt bereit wird.

Dies gibt eine Liste von (key, events) Tupeln zurück, eines für jedes bereite Datei-Objekt.

key ist die SelectorKey-Instanz, die einem bereiten Datei-Objekt entspricht. events ist eine Bitmaske der auf diesem Datei-Objekt bereiten Ereignisse.

Hinweis

Diese Methode kann zurückkehren, bevor ein Datei-Objekt bereit wird oder der Timeout abgelaufen ist, wenn der aktuelle Prozess ein Signal empfängt: in diesem Fall wird eine leere Liste zurückgegeben.

Geändert in Version 3.5: Der Selektor wird nun mit einem neu berechneten Timeout wiederholt, wenn er durch ein Signal unterbrochen wird, wenn der Signalhandler keine Ausnahme auslöst (siehe PEP 475 für die Begründung), anstatt eine leere Liste von Ereignissen vor dem Timeout zurückzugeben.

close()

Schließt den Selektor.

Dies muss aufgerufen werden, um sicherzustellen, dass alle zugrunde liegenden Ressourcen freigegeben werden. Der Selektor darf nicht verwendet werden, sobald er geschlossen wurde.

get_key(fileobj)

Gibt den Schlüssel zurück, der einem registrierten Datei-Objekt zugeordnet ist.

Dies gibt die SelectorKey-Instanz zurück, die diesem Datei-Objekt zugeordnet ist, oder löst eine KeyError aus, wenn das Datei-Objekt nicht registriert ist.

abstractmethod get_map()

Gibt eine Zuordnung von Datei-Objekten zu Selektorschlüsseln zurück.

Dies gibt eine Mapping-Instanz zurück, die registrierte Datei-Objekte ihren zugehörigen SelectorKey-Instanzen zuordnet.

class selectors.DefaultSelector

Die Standard-Selektor-Klasse, die die auf der aktuellen Plattform am effizientesten verfügbare Implementierung verwendet. Dies sollte die Standardwahl für die meisten Benutzer sein.

class selectors.SelectSelector

Selektor basierend auf select.select().

class selectors.PollSelector

Selektor basierend auf select.poll().

class selectors.EpollSelector

Selektor basierend auf select.epoll().

fileno()

Dies gibt den Dateideskriptor zurück, der vom zugrunde liegenden select.epoll()-Objekt verwendet wird.

class selectors.DevpollSelector

Selektor basierend auf select.devpoll().

fileno()

Dies gibt den Dateideskriptor zurück, der vom zugrunde liegenden select.devpoll()-Objekt verwendet wird.

Hinzugefügt in Version 3.5.

class selectors.KqueueSelector

Selektor basierend auf select.kqueue().

fileno()

Dies gibt den Dateideskriptor zurück, der vom zugrunde liegenden select.kqueue()-Objekt verwendet wird.

Beispiele

Hier ist eine einfache Implementierung eines Echo-Servers

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()  # Should be ready
    print('accepted', conn, 'from', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1000)  # Should be ready
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)  # Hope it won't block
    else:
        print('closing', conn)
        sel.unregister(conn)
        conn.close()

sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)