select — attente d’événements sur un ensemble de flux

Ce module fournit des fonctions permettant d’attendre efficacement qu’un ou plusieurs flux (objets de type fichier implémentant le protocole de flux, tels que les sockets, les UART et autres objets d’E/S) soient prêts pour la lecture ou l’écriture, au lieu d’effectuer une attente active ou de se bloquer sur un seul objet.

L’objet poll est l’interface recommandée : il s’adapte à un grand nombre de flux et n’effectue aucune allocation lorsqu’il est utilisé via poll.ipoll(). La fonction de niveau module select() est une interface de compatibilité moins efficace.

Exemple utilisant un objet poll

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())

Exemple utilisant la fonction de niveau module select()

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)

Fonctions

select.select(rlist: List, wlist: List, xlist: List, timeout: float | None = None) Tuple[List, List, List]

Attend qu’un ou plusieurs des objets flux donnés soient prêts, ou jusqu’à ce que timeout expire.

  • rlist est une liste d’objets à surveiller pour la lisibilité.

  • wlist est une liste d’objets à surveiller pour l’aptitude à l’écriture.

  • xlist est une liste d’objets à surveiller pour une condition d’erreur ou de déconnexion.

  • timeout est le temps d’attente maximal, en secondes (un float est accepté). S’il est omis ou vaut None, l’appel se bloque indéfiniment ; 0 retourne immédiatement (une interrogation non bloquante).

Retourne un tuple de 3 listes (rlist, wlist, xlist). Chaque liste retournée est le sous-ensemble de la liste d’entrée correspondante contenant les objets qui sont devenus prêts pour la lecture, prêts pour l’écriture, ou qui ont signalé une erreur/déconnexion, respectivement. Si timeout s’écoule sans que rien ne soit prêt, les trois listes sont vides.

Cette fonction est moins efficace que poll (elle reconstruit son ensemble d’interrogation interne à chaque appel) ; utilisez poll à la place lorsque c’est possible.

Constantes

select.POLLIN: int

Des données sont disponibles en lecture sur le flux.

select.POLLOUT: int

Le flux peut accepter davantage de données à écrire.

select.POLLERR: int

Une condition d’erreur s’est produite sur le flux. Il s’agit d’un événement non sollicité : il est signalé par poll.poll() / poll.ipoll() même s’il n’a pas été demandé dans l”eventmask, et il n’est pas valide de le passer en tant qu”eventmask d’entrée.

select.POLLHUP: int

Le flux a été déconnecté / raccroché. Il s’agit d’un événement non sollicité : il est signalé par poll.poll() / poll.ipoll() même s’il n’a pas été demandé dans l”eventmask, et il n’est pas valide de le passer en tant qu”eventmask d’entrée.

Classes

class select.poll

Crée un objet d’interrogation qui maintient un ensemble de flux enregistrés (ou de tout objet exposant le protocole de flux) et attend efficacement qu’un ou plusieurs d’entre eux devienne lisible, accessible en écriture, ou signale une condition exceptionnelle.

Les flux sont ajoutés avec register(), supprimés avec unregister(), et l’ensemble des événements à surveiller peut être modifié avec modify(). Une fois configuré, appelez poll() pour bloquer jusqu’à ce que quelque chose soit prêt (ou qu’un délai d’attente s’écoule), ou ipoll() pour une variante basée sur un itérateur sans allocation.

register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None

Enregistre le flux obj pour l’interrogation, en surveillant les événements donnés par eventmask (le OU logique de) :

eventmask vaut par défaut select.POLLIN | select.POLLOUT.

select.POLLHUP et select.POLLERR ne sont pas valides dans un eventmask d’entrée – ce sont des événements non sollicités qui sont signalés par poll() / ipoll() qu’ils aient été demandés ou non (cela correspond à la sémantique POSIX).

Il est correct d’appeler cette méthode plusieurs fois pour le même obj : un appel ultérieur met à jour le masque d’événements de obj, se comportant comme modify().

unregister(obj: Any) None

Supprime obj de l’ensemble des flux enregistrés. Il n’est pas erroné de désenregistrer un obj qui n’est pas actuellement enregistré (l’appel n’a alors aucun effet).

modify(obj: Any, eventmask: int) None

Change le masque d’événements d’un obj déjà enregistré en eventmask. Lève OSError avec errno.ENOENT si obj n’est pas enregistré.

poll(timeout: int = -1, /) List[Tuple]

Bloque jusqu’à ce qu’au moins un flux enregistré devienne prêt ou signale une condition exceptionnelle, puis retourne la liste des flux qui se sont déclenchés.

timeout est le temps d’attente maximal en millisecondes. S’il est omis ou vaut -1, l’appel se bloque indéfiniment ; 0 retourne immédiatement (une interrogation non bloquante).

Retourne une liste de tuples (obj, event, ...), un par flux qui s’est déclenché. obj est le flux enregistré et event est le OU bit à bit des indicateurs select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP qui se sont produits. Chaque tuple peut contenir des éléments supplémentaires définis par l’implémentation, donc ne supposez pas une longueur d’exactement 2. Si timeout s’écoule sans que rien ne soit prêt, une liste vide est retournée.

select.POLLHUP et select.POLLERR peuvent être retournés à tout moment (même s’ils n’ont pas été demandés) et doivent être traités – généralement en désenregistrant et en fermant le flux concerné – sinon les appels suivants continueront à retourner immédiatement avec ces indicateurs activés pour ce flux.

Toutes les fonctions de rappel planifiées en attente sont garanties de s’exécuter avant l’entrée dans la boucle d’interrogation.

Différence avec CPython

Les tuples retournés peuvent contenir plus de 2 éléments, comme décrit ci-dessus.

ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]

Comme poll(), mais au lieu de construire une liste, retourne un itérateur qui produit un tuple (obj, event, ...) à la fois. Cela évite d’allouer à chaque appel, ce qui est important pour les ordonnanceurs d’E/S asynchrones.

Le tuple produit est détenu par l’appelé : il est réutilisé (écrasé) à l’itération suivante, donc son contenu doit être consommé à l’intérieur du corps de la boucle et les références à celui-ci ne doivent pas être stockées.

timeout a la même signification que pour poll(). Si flags vaut 1, un comportement à déclenchement unique est utilisé : un flux dont l’événement s’est déclenché voit son masque d’événements effacé automatiquement (équivalent à poll.modify(obj, 0)), de sorte qu’aucun autre événement n’est signalé pour lui jusqu’à ce que son masque soit à nouveau défini avec modify().

Toutes les fonctions de rappel planifiées en attente sont garanties de s’exécuter avant l’entrée dans la boucle d’interrogation.

Différence avec CPython

Cette méthode est une extension de MicroPython.