select — așteaptă evenimente pe un set de fluxuri

Acest modul furnizează funcții pentru a aștepta în mod eficient până când unul sau mai multe fluxuri (obiecte de tip fișier care implementează protocolul de flux, cum ar fi socket-uri, UART-uri și alte obiecte de I/O) sunt pregătite pentru citire sau scriere, în loc de a aștepta activ (busy-waiting) sau a se bloca pe un singur obiect.

Obiectul poll este interfața recomandată: se scalează la multe fluxuri și nu efectuează alocări atunci când este folosit prin poll.ipoll(). Funcția la nivel de modul select() este o interfață de compatibilitate mai puțin eficientă.

Exemplu folosind un obiect 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())

Exemplu folosind funcția la nivel de modul 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)

Funcții

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

Așteaptă până când unul sau mai multe dintre obiectele de flux date sunt pregătite, sau până când expiră timeout.

  • rlist este o listă de obiecte de monitorizat pentru disponibilitatea la citire.

  • wlist este o listă de obiecte de monitorizat pentru disponibilitatea la scriere.

  • xlist este o listă de obiecte de monitorizat pentru o condiție de eroare sau de deconectare.

  • timeout este timpul maxim de așteptare, în secunde (se acceptă un float). Dacă este omis sau None, apelul se blochează la nesfârșit; 0 revine imediat (o interogare ne-blocantă).

Returnează un tuplu cu 3 liste (rlist, wlist, xlist). Fiecare listă returnată este subsetul listei de intrare corespunzătoare care conține obiectele care au devenit pregătite pentru citire, pregătite pentru scriere, sau care au semnalat o eroare/deconectare, respectiv. Dacă timeout expiră fără ca nimic să fie pregătit, toate cele trei liste sunt goale.

Această funcție este mai puțin eficientă decât poll (reconstruiește setul intern de interogare la fiecare apel); folosiți poll în schimb acolo unde este posibil.

Constante

select.POLLIN: int

Există date disponibile pentru citire din flux.

select.POLLOUT: int

Fluxul poate accepta mai multe date pentru scriere.

select.POLLERR: int

A apărut o condiție de eroare pe flux. Acesta este un eveniment nesolicitat: este raportat de poll.poll() / poll.ipoll() chiar dacă nu a fost cerut în eventmask și nu este valid să fie transmis ca eventmask de intrare.

select.POLLHUP: int

Fluxul a fost deconectat. Acesta este un eveniment nesolicitat: este raportat de poll.poll() / poll.ipoll() chiar dacă nu a fost cerut în eventmask și nu este valid să fie transmis ca eventmask de intrare.

Clase

class select.poll

Creează un obiect de interogare (polling) care menține un set de fluxuri înregistrate (sau orice obiecte care expun protocolul de flux) și așteaptă în mod eficient până când unul sau mai multe dintre ele devin disponibile pentru citire, scriere, sau semnalează o condiție excepțională.

Fluxurile sunt adăugate cu register(), eliminate cu unregister(), iar setul de evenimente de urmărit poate fi schimbat cu modify(). Odată configurat, apelați poll() pentru a bloca până când ceva este pregătit (sau expiră un timeout), sau ipoll() pentru o variantă bazată pe iterator, fără alocări.

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

Înregistrează fluxul obj pentru interogare, urmărind evenimentele date de eventmask (sau-logic între):

eventmask are valoarea implicită select.POLLIN | select.POLLOUT.

select.POLLHUP și select.POLLERR nu sunt valide într-un eventmask de intrare – ele sunt evenimente nesolicitate care sunt raportate de poll() / ipoll() indiferent dacă au fost cerute sau nu (acest lucru corespunde semanticii POSIX).

Este în regulă să apelați această metodă de mai multe ori pentru același obj: un apel ulterior actualizează masca de evenimente a lui obj, comportându-se ca modify().

unregister(obj: Any) None

Elimină obj din setul de fluxuri înregistrate. Nu este o eroare să dezînregistrați un obj care nu este înregistrat în prezent (în acest caz apelul nu are niciun efect).

modify(obj: Any, eventmask: int) None

Schimbă masca de evenimente pentru un obj deja înregistrat la eventmask. Ridică OSError cu errno.ENOENT dacă obj nu este înregistrat.

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

Blochează până când cel puțin un flux înregistrat devine pregătit sau semnalează o condiție excepțională, apoi returnează lista fluxurilor care s-au declanșat.

timeout este timpul maxim de așteptare în milisecunde. Dacă este omis sau -1, apelul se blochează la nesfârșit; 0 revine imediat (o interogare ne-blocantă).

Returnează o listă de tupluri (obj, event, ...), câte unul pentru fiecare flux care s-a declanșat. obj este fluxul înregistrat, iar event este sau-logic la nivel de biți între indicatorii select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP care au apărut. Fiecare tuplu poate conține elemente suplimentare definite de implementare, deci nu presupuneți o lungime de exact 2. Dacă timeout expiră fără ca nimic să fie pregătit, se returnează o listă goală.

select.POLLHUP și select.POLLERR pot fi returnate în orice moment (chiar dacă nu au fost cerute) și trebuie tratate – de obicei prin dezînregistrarea și închiderea fluxului afectat – altfel apelurile ulterioare vor continua să revină imediat cu acești indicatori setați pentru acel flux.

Orice funcții de retroapelare (callback) programate în așteptare sunt garantate să ruleze înainte de intrarea în bucla de interogare.

Diferență față de CPython

Tuplurile returnate pot conține mai mult de 2 elemente, așa cum este descris mai sus.

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

La fel ca poll(), dar în loc să construiască o listă, returnează un iterator care produce câte un tuplu (obj, event, ...) la un moment dat. Acest lucru evită alocarea la fiecare apel, ceea ce este important pentru planificatoarele de I/O asincron.

Tuplul produs este deținut de apelat (callee-owned): este reutilizat (suprascris) la următoarea iterație, deci conținutul său trebuie consumat în interiorul corpului buclei, iar referințele către el nu trebuie stocate.

timeout are aceeași semnificație ca pentru poll(). Dacă flags este 1, se folosește un comportament cu o singură declanșare (one-shot): unui flux al cărui eveniment s-a declanșat i se șterge automat masca de evenimente (echivalent cu poll.modify(obj, 0)), astfel încât nu se mai raportează evenimente pentru el până când masca sa nu este setată din nou cu modify().

Orice funcții de retroapelare (callback) programate în așteptare sunt garantate să ruleze înainte de intrarea în bucla de interogare.

Diferență față de CPython

Această metodă este o extensie MicroPython.