select — aguarda por eventos em um conjunto de streams

Este módulo fornece funções para aguardar de forma eficiente até que um ou mais streams (objetos do tipo arquivo que implementam o protocolo de stream, como sockets, UARTs e outros objetos de E/S) estejam prontos para leitura ou escrita, em vez de fazer busy-wait ou bloquear em um único objeto.

O objeto poll é a interface recomendada: ele escala para muitos streams e é livre de alocação quando usado via poll.ipoll(). A função select() em nível de módulo é uma interface de compatibilidade menos eficiente.

Exemplo usando um 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())

Exemplo usando a função select() em nível 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)

Funções

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

Aguarda até que um ou mais dos objetos de stream fornecidos estejam prontos, ou até que timeout expire.

  • rlist é uma lista de objetos a monitorar quanto à legibilidade.

  • wlist é uma lista de objetos a monitorar quanto à possibilidade de escrita.

  • xlist é uma lista de objetos a monitorar quanto a uma condição de erro ou desconexão.

  • timeout é o tempo máximo de espera, em segundos (um float é aceito). Se for omitido ou None, a chamada bloqueia indefinidamente; 0 retorna imediatamente (uma sondagem não bloqueante).

Retorna uma tupla de 3 listas (rlist, wlist, xlist). Cada lista retornada é o subconjunto da lista de entrada correspondente que contém os objetos que ficaram prontos para leitura, prontos para escrita ou que sinalizaram um erro/desconexão, respectivamente. Se timeout decorrer sem nada pronto, as três listas ficam vazias.

Esta função é menos eficiente que poll (ela reconstrói seu conjunto de sondagem interno a cada chamada); use poll em vez disso sempre que possível.

Constantes

select.POLLIN: int

Há dados disponíveis para leitura no stream.

select.POLLOUT: int

O stream pode aceitar mais dados a serem escritos.

select.POLLERR: int

Ocorreu uma condição de erro no stream. Este é um evento não solicitado: ele é relatado por poll.poll() / poll.ipoll() mesmo que não tenha sido requisitado no eventmask, e não é válido passá-lo como um eventmask de entrada.

select.POLLHUP: int

O stream foi desconectado. Este é um evento não solicitado: ele é relatado por poll.poll() / poll.ipoll() mesmo que não tenha sido requisitado no eventmask, e não é válido passá-lo como um eventmask de entrada.

Classes

class select.poll

Cria um objeto de sondagem que mantém um conjunto de streams registrados (ou quaisquer objetos que exponham o protocolo de stream) e aguarda de forma eficiente até que um ou mais deles fiquem prontos para leitura, escrita ou sinalizem uma condição excepcional.

Streams são adicionados com register(), removidos com unregister(), e o conjunto de eventos a observar pode ser alterado com modify(). Uma vez configurado, chame poll() para bloquear até que algo esteja pronto (ou um timeout decorra), ou ipoll() para uma variante baseada em iterador e livre de alocação.

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

Registra o stream obj para sondagem, observando os eventos fornecidos por eventmask (o OR lógico de):

eventmask tem como padrão select.POLLIN | select.POLLOUT.

select.POLLHUP e select.POLLERR não são válidos em um eventmask de entrada – são eventos não solicitados que são relatados por poll() / ipoll() independentemente de terem sido requisitados (isso corresponde à semântica POSIX).

É permitido chamar este método mais de uma vez para o mesmo obj: uma chamada subsequente atualiza a máscara de eventos de obj, comportando-se como modify().

unregister(obj: Any) None

Remove obj do conjunto de streams registrados. Não é um erro cancelar o registro de um obj que não está registrado no momento (a chamada não tem efeito nesse caso).

modify(obj: Any, eventmask: int) None

Altera a máscara de eventos de um obj já registrado para eventmask. Levanta OSError com errno.ENOENT se obj não estiver registrado.

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

Bloqueia até que pelo menos um stream registrado fique pronto ou sinalize uma condição excepcional, e então retorna a lista de streams que dispararam.

timeout é o tempo máximo de espera em milissegundos. Se for omitido ou -1, a chamada bloqueia indefinidamente; 0 retorna imediatamente (uma sondagem não bloqueante).

Retorna uma lista de tuplas (obj, event, ...), uma por stream que disparou. obj é o stream registrado e event é o OR bit a bit das flags select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP que ocorreram. Cada tupla pode conter elementos adicionais definidos pela implementação, portanto não assuma um comprimento de exatamente 2. Se timeout decorrer sem nada pronto, uma lista vazia é retornada.

select.POLLHUP e select.POLLERR podem ser retornados a qualquer momento (mesmo que não requisitados) e devem ser tratados – normalmente cancelando o registro e fechando o stream afetado – caso contrário, chamadas subsequentes continuarão retornando imediatamente com essas flags setadas para aquele stream.

Quaisquer callbacks agendados pendentes têm a garantia de serem executados antes de o laço de sondagem ser iniciado.

Diferença em relação ao CPython

As tuplas retornadas podem conter mais de 2 elementos, conforme descrito acima.

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

Como poll(), mas, em vez de construir uma lista, retorna um iterador que produz uma tupla (obj, event, ...) por vez. Isso evita alocação a cada chamada, o que é importante para escalonadores de E/S assíncrona.

A tupla produzida é de propriedade do chamado: ela é reutilizada (sobrescrita) na próxima iteração, portanto seu conteúdo deve ser consumido dentro do corpo do laço e referências a ela não devem ser armazenadas.

timeout tem o mesmo significado que em poll(). Se flags for 1, é usado o comportamento de disparo único: um stream cujo evento disparou tem sua máscara de eventos automaticamente limpa (equivalente a poll.modify(obj, 0)), de modo que nenhum evento adicional é relatado para ele até que sua máscara seja setada novamente com modify().

Quaisquer callbacks agendados pendentes têm a garantia de serem executados antes de o laço de sondagem ser iniciado.

Diferença em relação ao CPython

Este método é uma extensão do MicroPython.