selectors — E/A-Multiplexen auf hoher Ebene

Added in version 3.4.

Quellcode: Lib/selectors.py


Einführung

Dieses Modul ermöglicht effizientes E/A-Multiplexen auf hoher Ebene, aufbauend auf den Grundoperationen des Moduls select. Wir empfehlen, dieses Modul zu verwenden, sofern du nicht genaue Kontrolle über die verwendeten Grundoperationen des Betriebssystems brauchst.

Es definiert die abstrakte Basisklasse BaseSelector sowie mehrere konkrete Umsetzungen (KqueueSelector, EpollSelector …), mit denen sich auf die Meldung warten lässt, dass mehrere Dateiobjekte für E/A bereit sind. Im Folgenden meint „Dateiobjekt“ jedes Objekt mit einer Methode fileno() oder einen rohen Dateideskriptor. Siehe Dateiobjekt.

DefaultSelector ist ein Alias für die effizienteste Umsetzung, die auf der aktuellen Plattform zur Verfügung steht. Für die meisten ist das die richtige Wahl.

Bemerkung

Welche Arten von Dateiobjekten unterstützt werden, hängt von der Plattform ab: Unter Windows werden Sockets unterstützt, Pipes dagegen nicht. Unter Unix beides. Möglicherweise werden auch weitere Arten unterstützt, etwa FIFOs oder besondere Gerätedateien.

Siehe auch

select

Modul für E/A-Multiplexen auf niedriger Ebene.

Verfügbarkeit: not WASI.

Dieses Modul arbeitet nicht oder steht nicht zur Verfügung auf WebAssembly. Näheres unter WebAssembly-Plattformen.

Klassen

Klassenhierarchie:

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

Im Folgenden ist events eine Bitmaske, die angibt, auf welche E/A-Ereignisse bei einem bestimmten Dateiobjekt gewartet werden soll. Sie kann eine Kombination der folgenden Konstanten des Moduls sein:

Konstante

Bedeutung

selectors.EVENT_READ

Zum Lesen bereit

selectors.EVENT_WRITE

Zum Schreiben bereit

class selectors.SelectorKey

Ein SelectorKey ist ein namedtuple, das ein Dateiobjekt mit seinem zugrunde liegenden Dateideskriptor, der gewählten Ereignismaske und den angehängten Daten verbindet. Mehrere Methoden von BaseSelector geben ihn zurück.

fileobj

Registriertes Dateiobjekt.

fd

Zugrunde liegender Dateideskriptor.

events

Ereignisse, auf die bei diesem Dateiobjekt gewartet werden muss.

data

Optionale undurchsichtige Daten, die diesem Dateiobjekt zugeordnet sind. Darin ließe sich zum Beispiel eine Sitzungskennung je Client ablegen.

class selectors.BaseSelector

Mit einem BaseSelector wartet man darauf, dass mehrere Dateiobjekte für E/A-Ereignisse bereit sind. Er unterstützt das An- und Abmelden von Dateiströmen sowie eine Methode, mit der sich auf E/A-Ereignisse dieser Ströme warten lässt, mit optionaler Zeitgrenze. Er ist eine abstrakte Basisklasse und lässt sich daher nicht instanzieren. Verwende stattdessen DefaultSelector oder, wenn du ausdrücklich eine bestimmte Umsetzung willst und deine Plattform sie unterstützt, eine von SelectSelector, KqueueSelector und so weiter. BaseSelector und seine konkreten Umsetzungen unterstützen das Kontextmanager-Protokoll.

abstractmethod register(fileobj, events, data=None)

Meldet ein Dateiobjekt zur Auswahl an und überwacht es auf E/A-Ereignisse.

fileobj ist das zu überwachende Dateiobjekt. Es kann entweder ein Dateideskriptor als ganze Zahl oder ein Objekt mit einer Methode fileno() sein. events ist eine Bitmaske der zu überwachenden Ereignisse. data ist ein undurchsichtiges Objekt.

Gibt eine neue SelectorKey-Instanz zurück oder löst ValueError aus, wenn Ereignismaske oder Dateideskriptor ungültig sind, beziehungsweise KeyError, wenn das Dateiobjekt bereits angemeldet ist.

abstractmethod unregister(fileobj)

Meldet ein Dateiobjekt von der Auswahl ab und nimmt es aus der Überwachung. Ein Dateiobjekt sollte abgemeldet werden, bevor es geschlossen wird.

fileobj muss ein zuvor angemeldetes Dateiobjekt sein.

Gibt die zugehörige SelectorKey-Instanz zurück oder löst KeyError aus, wenn fileobj nicht angemeldet ist. ValueError wird ausgelöst, wenn fileobj ungültig ist, etwa weil es keine Methode fileno() hat oder deren Rückgabewert ungültig ist.

modify(fileobj, events, data=None)

Ändert die überwachten Ereignisse oder die angehängten Daten eines angemeldeten Dateiobjekts.

Das entspricht BaseSelector.unregister(fileobj) gefolgt von BaseSelector.register(fileobj, events, data), lässt sich aber effizienter umsetzen.

Gibt eine neue SelectorKey-Instanz zurück oder löst ValueError aus, wenn Ereignismaske oder Dateideskriptor ungültig sind, beziehungsweise KeyError, wenn das Dateiobjekt nicht angemeldet ist.

abstractmethod select(timeout=None)

Wartet, bis einige angemeldete Dateiobjekte bereit sind oder die Zeitgrenze abläuft.

Ist timeout > 0, gibt das die längste Wartezeit in Sekunden an. Ist timeout <= 0, blockiert der Aufruf nicht, sondern meldet die derzeit bereiten Dateiobjekte. Ist timeout None, blockiert der Aufruf, bis ein überwachtes Dateiobjekt bereit wird.

Gibt eine Liste von Tupeln (key, events) zurück, eines für jedes bereite Dateiobjekt.

key ist die SelectorKey-Instanz des bereiten Dateiobjekts. events ist eine Bitmaske der Ereignisse, die bei diesem Dateiobjekt bereit sind.

Bemerkung

Diese Methode kann zurückkehren, bevor ein Dateiobjekt bereit ist oder die Zeitgrenze abgelaufen ist, nämlich wenn der aktuelle Prozess ein Signal empfängt. Dann wird eine leere Liste zurückgegeben.

Geändert in Version 3.5: Wird der Selektor von einem Signal unterbrochen und löst der Signalhandler keine Ausnahme aus, wird er jetzt mit neu berechneter Zeitgrenze erneut versucht, statt vor Ablauf der Zeitgrenze eine leere Ereignisliste zurückzugeben. Die Begründung steht in PEP 475.

close()

Schließt den Selektor.

Das muss aufgerufen werden, damit alle zugrunde liegenden Ressourcen freigegeben werden. Nach dem Schließen sollte der Selektor nicht mehr verwendet werden.

get_key(fileobj)

Gibt den Schlüssel zurück, der zu einem angemeldeten Dateiobjekt gehört.

Gibt die SelectorKey-Instanz zurück, die zu diesem Dateiobjekt gehört, oder löst KeyError aus, wenn das Dateiobjekt nicht angemeldet ist.

abstractmethod get_map()

Gibt eine Zuordnung von Dateiobjekten zu Selektorschlüsseln zurück.

Gibt eine Mapping-Instanz zurück, die angemeldete Dateiobjekte auf die zugehörige SelectorKey-Instanz abbildet.

class selectors.DefaultSelector

Die voreingestellte Selektorklasse. Sie verwendet die effizienteste Umsetzung, die auf der aktuellen Plattform zur Verfügung steht. Für die meisten ist das die richtige Wahl.

class selectors.SelectSelector

Selektor auf Grundlage von select.select().

class selectors.PollSelector

Selektor auf Grundlage von select.poll().

class selectors.EpollSelector

Selektor auf Grundlage von select.epoll().

fileno()

Gibt den Dateideskriptor zurück, den das zugrunde liegende select.epoll()-Objekt verwendet.

class selectors.DevpollSelector

Selektor auf Grundlage von select.devpoll().

fileno()

Gibt den Dateideskriptor zurück, den das zugrunde liegende select.devpoll()-Objekt verwendet.

Added in version 3.5.

class selectors.KqueueSelector

Selektor auf Grundlage von select.kqueue().

fileno()

Gibt den Dateideskriptor zurück, den das zugrunde liegende select.kqueue()-Objekt verwendet.

Beispiele

Hier eine einfache Umsetzung 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)