select — esperar eventos en un conjunto de flujos¶
Este módulo proporciona funciones para esperar de forma eficiente hasta que uno o más flujos (objetos de tipo archivo que implementan el protocolo de flujo, como sockets, UART y otros objetos de E/S) estén listos para lectura o escritura, en lugar de hacer una espera activa o bloquearse en un solo objeto.
El objeto poll es la interfaz recomendada: escala a muchos flujos y no realiza asignaciones de memoria cuando se usa a través de poll.ipoll(). La función select() a nivel de módulo es una interfaz de compatibilidad menos eficiente.
Ejemplo usando un objeto 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())
Ejemplo usando la función select() a nivel de módulo:
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)
Funciones¶
- select.select(rlist: List, wlist: List, xlist: List, timeout: float | None = None) Tuple[List, List, List]¶
Espera hasta que uno o más de los objetos de flujo dados estén listos, o hasta que expire timeout.
rlist es una lista de objetos a monitorizar para comprobar su disponibilidad de lectura.
wlist es una lista de objetos a monitorizar para comprobar su disponibilidad de escritura.
xlist es una lista de objetos a monitorizar para detectar una condición de error o de desconexión.
timeout es el tiempo máximo de espera, en segundos (se acepta un valor de coma flotante). Si se omite o es
None, la llamada se bloquea indefinidamente;0retorna de inmediato (un sondeo no bloqueante).
Devuelve una tupla de 3 listas
(rlist, wlist, xlist). Cada lista devuelta es el subconjunto de la lista de entrada correspondiente que contiene los objetos que pasaron a estar listos para lectura, listos para escritura, o que señalaron un error/desconexión, respectivamente. Si transcurre timeout sin que nada esté listo, las tres listas están vacías.Esta función es menos eficiente que
poll(reconstruye su conjunto interno de sondeo en cada llamada); usepollen su lugar siempre que sea posible.
Constantes¶
- select.POLLERR: int¶
Ocurrió una condición de error en el flujo. Este es un evento no solicitado: lo notifican
poll.poll()/poll.ipoll()aunque no se haya solicitado en eventmask, y no es válido pasarlo como eventmask de entrada.
- select.POLLHUP: int¶
El flujo se desconectó / cerró. Este es un evento no solicitado: lo notifican
poll.poll()/poll.ipoll()aunque no se haya solicitado en eventmask, y no es válido pasarlo como eventmask de entrada.
Clases¶
- class select.poll¶
Crea un objeto de sondeo que mantiene un conjunto de flujos registrados (o cualquier objeto que exponga el protocolo de flujo) y espera de forma eficiente hasta que uno o más de ellos pase a estar listo para lectura, escritura, o señale una condición excepcional.
Los flujos se añaden con
register(), se eliminan conunregister(), y el conjunto de eventos a observar puede cambiarse conmodify(). Una vez configurado, llame apoll()para bloquear hasta que algo esté listo (o transcurra un tiempo de espera), o aipoll()para una variante basada en iterador sin asignación de memoria.- register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None¶
Registra el flujo obj para sondeo, observando los eventos indicados por eventmask (el OR lógico de):
select.POLLIN– hay datos disponibles para leerselect.POLLOUT– el flujo puede aceptar más datos para escribir
eventmask tiene como valor predeterminado
select.POLLIN | select.POLLOUT.select.POLLHUPyselect.POLLERRno son válidos en un eventmask de entrada: son eventos no solicitados que notificanpoll()/ipoll()independientemente de si se solicitaron (esto coincide con la semántica de POSIX).Está permitido llamar a este método más de una vez para el mismo obj: una llamada posterior actualiza la máscara de eventos de obj, comportándose como
modify().
- unregister(obj: Any) None¶
Elimina obj del conjunto de flujos registrados. No es un error dar de baja un obj que no está registrado actualmente (en ese caso la llamada no tiene ningún efecto).
- modify(obj: Any, eventmask: int) None¶
Cambia la máscara de eventos de un obj ya registrado a eventmask. Genera
OSErrorconerrno.ENOENTsi obj no está registrado.
- poll(timeout: int = -1, /) List[Tuple]¶
Se bloquea hasta que al menos un flujo registrado pase a estar listo o señale una condición excepcional, y luego devuelve la lista de flujos que se activaron.
timeout es el tiempo máximo de espera en milisegundos. Si se omite o es
-1, la llamada se bloquea indefinidamente;0retorna de inmediato (un sondeo no bloqueante).Devuelve una lista de tuplas
(obj, event, ...), una por cada flujo que se activó.objes el flujo registrado yeventes el OR a nivel de bits de las banderasselect.POLLIN/select.POLLOUT/select.POLLERR/select.POLLHUPque ocurrieron. Cada tupla puede contener elementos adicionales definidos por la implementación, así que no asuma una longitud de exactamente 2. Si transcurre timeout sin que nada esté listo, se devuelve una lista vacía.select.POLLHUPyselect.POLLERRpueden devolverse en cualquier momento (incluso si no se solicitaron) y debe actuarse sobre ellos – normalmente dando de baja y cerrando el flujo afectado – de lo contrario, las llamadas posteriores seguirán retornando de inmediato con estas banderas activadas para ese flujo.Se garantiza que todas las funciones de retorno (callbacks) programadas pendientes se ejecuten antes de entrar en el bucle de sondeo.
Diferencia con CPython
Las tuplas devueltas pueden contener más de 2 elementos, como se describe arriba.
- ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]¶
Como
poll(), pero en lugar de construir una lista devuelve un iterador que produce una tupla(obj, event, ...)a la vez. Esto evita asignar memoria en cada llamada, lo cual es importante para los planificadores de E/S asíncrona.La tupla producida es propiedad del invocado (callee): se reutiliza (se sobrescribe) en la siguiente iteración, por lo que su contenido debe consumirse dentro del cuerpo del bucle y no deben almacenarse referencias a ella.
timeout tiene el mismo significado que en
poll(). Si flags es1, se usa un comportamiento de un solo disparo (one-shot): un flujo cuyo evento se activó tiene su máscara de eventos borrada automáticamente (equivalente apoll.modify(obj, 0)), de modo que no se notifican más eventos para él hasta que su máscara se vuelva a establecer conmodify().Se garantiza que todas las funciones de retorno (callbacks) programadas pendientes se ejecuten antes de entrar en el bucle de sondeo.
Diferencia con CPython
Este método es una extensión de MicroPython.