select — események bevárása adatfolyamok egy halmazán

Ez a modul olyan függvényeket biztosít, amelyekkel hatékonyan lehet megvárni, amíg egy vagy több adatfolyam (az adatfolyam-protokollt megvalósító, fájlszerű objektum, például socketek, UART-ok és más I/O-objektumok) olvasásra vagy írásra kész lesz, ahelyett, hogy egyetlen objektumon aktívan várakoznánk vagy blokkolnánk.

A poll objektum az ajánlott interfész: sok adatfolyamra is jól skálázódik, és allokációmentes, ha a poll.ipoll() metóduson keresztül használjuk. A modulszintű select() függvény egy kevésbé hatékony kompatibilitási interfész.

poll objektumot használó példa:

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

A modulszintű select() függvényt használó példa:

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)

Függvények

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

Megvárja, amíg a megadott adatfolyam-objektumok közül egy vagy több készen áll, vagy amíg a timeout le nem jár.

  • Az rlist az olvashatóság szempontjából figyelendő objektumok listája.

  • A wlist az írhatóság szempontjából figyelendő objektumok listája.

  • Az xlist a hiba- vagy megszakadási állapot szempontjából figyelendő objektumok listája.

  • A timeout a várakozás maximális ideje másodpercben (float is elfogadott). Ha elhagyják vagy None, a hívás határozatlan ideig blokkol; a 0 azonnal visszatér (nem blokkoló lekérdezés).

Egy listákból álló 3 elemű tuple-t ad vissza: (rlist, wlist, xlist). Minden visszaadott lista a megfelelő bemeneti lista azon részhalmaza, amely az olvasásra kész, az írásra kész, illetve a hibát/megszakadást jelző objektumokat tartalmazza. Ha a timeout úgy jár le, hogy semmi sem áll készen, mindhárom lista üres.

Ez a függvény kevésbé hatékony, mint a poll (minden híváskor újraépíti a belső lekérdezési halmazát); ahol lehet, inkább a poll osztályt használja.

Konstansok

select.POLLIN: int

Adat áll rendelkezésre olvasásra az adatfolyamból.

select.POLLOUT: int

Az adatfolyam további írandó adatot tud fogadni.

select.POLLERR: int

Hibaállapot lépett fel az adatfolyamon. Ez egy kéretlen esemény: a poll.poll() / poll.ipoll() akkor is jelzi, ha nem kérték az eventmask-ban, és bemeneti eventmask-ként nem érvényes átadni.

select.POLLHUP: int

Az adatfolyam megszakadt / lekapcsolódott. Ez egy kéretlen esemény: a poll.poll() / poll.ipoll() akkor is jelzi, ha nem kérték az eventmask-ban, és bemeneti eventmask-ként nem érvényes átadni.

Osztályok

class select.poll

Létrehoz egy lekérdező objektumot, amely fenntartja a regisztrált adatfolyamok (vagy bármely, az adatfolyam-protokollt kínáló objektum) egy halmazát, és hatékonyan megvárja, amíg ezek közül egy vagy több olvashatóvá, írhatóvá válik, vagy kivételes állapotot jelez.

Az adatfolyamok a register() metódussal adhatók hozzá, a unregister() metódussal távolíthatók el, a figyelendő események halmaza pedig a modify() metódussal módosítható. A konfigurálás után hívja a poll() metódust, hogy blokkoljon, amíg valami készen nem áll (vagy le nem jár az időkorlát), vagy a ipoll() metódust egy allokációmentes, iterátoralapú változatért.

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

Regisztrálja a(z) obj adatfolyamot a lekérdezéshez, az eventmask által megadott eseményekre figyelve (a következők logikai VAGY-a):

Az eventmask alapértelmezett értéke select.POLLIN | select.POLLOUT.

A select.POLLHUP és a select.POLLERR nem érvényes a bemeneti eventmask-ban – ezek kéretlen események, amelyeket a poll() / ipoll() attól függetlenül jelez, hogy kérték-e őket (ez megfelel a POSIX szemantikának).

Ezt a metódust ugyanarra a(z) obj-ra többször is meg lehet hívni: egy következő hívás frissíti az obj eseménymaszkját, a modify() metódushoz hasonlóan viselkedve.

unregister(obj: Any) None

Eltávolítja a(z) obj-t a regisztrált adatfolyamok halmazából. Nem hiba egy olyan obj regisztrációjának megszüntetése, amely jelenleg nincs regisztrálva (a hívásnak ebben az esetben nincs hatása).

modify(obj: Any, eventmask: int) None

Megváltoztatja egy már regisztrált obj eseménymaszkját az eventmask értékre. OSError kivételt vált ki errno.ENOENT kóddal, ha a(z) obj nincs regisztrálva.

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

Blokkol, amíg legalább egy regisztrált adatfolyam készen nem áll, vagy kivételes állapotot nem jelez, majd visszaadja a megszólalt adatfolyamok listáját.

A timeout a várakozás maximális ideje ezredmásodpercben. Ha elhagyják vagy -1, a hívás határozatlan ideig blokkol; a 0 azonnal visszatér (nem blokkoló lekérdezés).

Egy (obj, event, ...) tuple-ökből álló listát ad vissza, egyet minden megszólalt adatfolyamhoz. Az obj a regisztrált adatfolyam, az event pedig a bekövetkezett select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP jelzők bitenkénti VAGY-a. Minden tuple tartalmazhat további, implementációfüggő elemeket, ezért ne feltételezze, hogy pontosan 2 hosszúságú. Ha a timeout úgy jár le, hogy semmi sem áll készen, üres listát ad vissza.

A select.POLLHUP és a select.POLLERR bármikor visszaadható (akkor is, ha nem kérték), és cselekedni kell rájuk – jellemzően az érintett adatfolyam regisztrációjának megszüntetésével és lezárásával –, különben a következő hívások továbbra is azonnal visszatérnek, ezekkel a jelzőkkel beállítva az adott adatfolyamra.

A függőben lévő ütemezett visszahívások garantáltan lefutnak, mielőtt a lekérdezési ciklusba lépne.

Eltérés a CPythontól

A visszaadott tuple-ök a fent leírtak szerint 2-nél több elemet is tartalmazhatnak.

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

Hasonló a poll() metódushoz, de lista építése helyett egy iterátort ad vissza, amely egyszerre egy (obj, event, ...) tuple-t szolgáltat. Ez elkerüli a minden híváskori allokációt, ami fontos az aszinkron I/O-ütemezőknél.

A szolgáltatott tuple a hívott fél tulajdonában van: a következő iterációnál újrahasználódik (felülíródik), ezért tartalmát a ciklus törzsén belül kell feldolgozni, és nem szabad rá hivatkozást tárolni.

A timeout jelentése ugyanaz, mint a poll() esetén. Ha a flags értéke 1, akkor egyszeri (one-shot) viselkedés érvényesül: annak az adatfolyamnak, amelynek eseménye megszólalt, automatikusan törlődik az eseménymaszkja (a poll.modify(obj, 0)-val egyenértékűen), így addig nem jelez róla több eseményt, amíg a maszkját újra be nem állítják a modify() metódussal.

A függőben lévő ütemezett visszahívások garantáltan lefutnak, mielőtt a lekérdezési ciklusba lépne.

Eltérés a CPythontól

Ez a metódus egy MicroPython-bővítmény.