select — čekání na události na množině streamů

Tento modul poskytuje funkce pro efektivní čekání, dokud nebude jeden nebo více streamů (objektů podobných souborům implementujících stream protokol, jako jsou sokety, UARTy a další I/O objekty) připraveno ke čtení nebo zápisu, namísto aktivního čekání nebo blokování na jediném objektu.

Objekt poll je doporučené rozhraní: škáluje na mnoho streamů a je bez alokace, je-li použit přes poll.ipoll(). Funkce select() na úrovni modulu je méně efektivní kompatibilní rozhraní.

Příklad použití objektu 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())

Příklad použití funkce select() na úrovni modulu:

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)

Funkce

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

Čeká, dokud nebude jeden nebo více daných stream objektů připraveno, nebo dokud nevyprší timeout.

  • rlist je seznam objektů, které se mají monitorovat na čitelnost.

  • wlist je seznam objektů, které se mají monitorovat na zapisovatelnost.

  • xlist je seznam objektů, které se mají monitorovat na chybový stav nebo odpojení.

  • timeout je maximální doba čekání v sekundách (akceptuje se float). Pokud je vynechán nebo None, volání blokuje neomezeně; 0 se vrátí okamžitě (neblokující dotaz).

Vrací 3-tici seznamů (rlist, wlist, xlist). Každý vrácený seznam je podmnožinou odpovídajícího vstupního seznamu obsahující objekty, které se staly připravenými ke čtení, připravenými k zápisu, respektive signalizovaly chybu/odpojení. Pokud timeout uplyne, aniž by bylo cokoli připraveno, všechny tři seznamy jsou prázdné.

Tato funkce je méně efektivní než poll (na každém volání znovu sestavuje svou interní množinu pro dotazování); kde je to možné, použijte místo ní poll.

Konstanty

select.POLLIN: int

Ze streamu jsou dostupná data ke čtení.

select.POLLOUT: int

Stream může přijmout další data k zápisu.

select.POLLERR: int

Na streamu došlo k chybovému stavu. Toto je nevyžádaná událost: je hlášena metodou poll.poll() / poll.ipoll(), i když nebyla vyžádána v eventmask, a není platné ji předat jako vstupní eventmask.

select.POLLHUP: int

Stream byl odpojen / rozpojen. Toto je nevyžádaná událost: je hlášena metodou poll.poll() / poll.ipoll(), i když nebyla vyžádána v eventmask, a není platné ji předat jako vstupní eventmask.

Třídy

class select.poll

Vytvoří dotazovací objekt, který udržuje množinu registrovaných streamů (nebo libovolných objektů vystavujících stream protokol) a efektivně čeká, dokud se jeden nebo více z nich nestane čitelným, zapisovatelným nebo nesignalizuje výjimečný stav.

Streamy se přidávají pomocí register(), odebírají pomocí unregister() a množinu událostí ke sledování lze změnit pomocí modify(). Po nakonfigurování zavolejte poll() pro blokování, dokud nebude něco připraveno (nebo neuplyne timeout), nebo ipoll() pro variantu bez alokace založenou na iterátoru.

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

Zaregistruje stream obj pro dotazování a sleduje události dané pomocí eventmask (logický OR z):

eventmask má výchozí hodnotu select.POLLIN | select.POLLOUT.

select.POLLHUP a select.POLLERR nejsou platné ve vstupním eventmask – jsou to nevyžádané události, které jsou hlášeny metodou poll() / ipoll() bez ohledu na to, zda byly vyžádány (to odpovídá sémantice POSIX).

Je v pořádku zavolat tuto metodu pro stejný obj více než jednou: následné volání aktualizuje masku událostí obj a chová se jako modify().

unregister(obj: Any) None

Odebere obj z množiny registrovaných streamů. Není chybou odregistrovat obj, který momentálně není registrován (volání v takovém případě nemá žádný účinek).

modify(obj: Any, eventmask: int) None

Změní masku událostí pro již registrovaný obj na eventmask. Vyvolá OSError s errno.ENOENT, pokud obj není registrován.

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

Blokuje, dokud se alespoň jeden registrovaný stream nestane připraveným nebo nesignalizuje výjimečný stav, poté vrátí seznam streamů, které vyvolaly událost.

timeout je maximální doba čekání v milisekundách. Pokud je vynechán nebo -1, volání blokuje neomezeně; 0 se vrátí okamžitě (neblokující dotaz).

Vrací seznam n-tic (obj, event, ...), jednu pro každý stream, který vyvolal událost. obj je registrovaný stream a event je bitový OR příznaků select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP, které nastaly. Každá n-tice může obsahovat další implementačně definované prvky, takže nepředpokládejte délku přesně 2. Pokud timeout uplyne, aniž by bylo cokoli připraveno, vrátí se prázdný seznam.

select.POLLHUP a select.POLLERR mohou být vráceny kdykoli (i když nebyly vyžádány) a musí se na ně reagovat – typicky odregistrováním a uzavřením postiženého streamu – jinak následná volání budou pro tento stream stále vracet okamžitě s nastavenými těmito příznaky.

Je zaručeno, že všechny čekající naplánované callbacky se spustí před vstupem do dotazovací smyčky.

Rozdíl oproti CPythonu

Vrácené n-tice mohou obsahovat více než 2 prvky, jak je popsáno výše.

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

Jako poll(), ale namísto sestavování seznamu vrací iterátor, který poskytuje jednu n-tici (obj, event, ...) po druhé. Tím se zabrání alokaci na každém volání, což je důležité pro asynchronní I/O plánovače.

Poskytnutá n-tice je vlastněná volaným: při další iteraci je znovu použita (přepsána), takže její obsah musí být zpracován v těle smyčky a odkazy na ni nesmí být uloženy.

timeout má stejný význam jako u poll(). Pokud je flags 1, použije se jednorázové chování: streamu, jehož událost nastala, se automaticky vymaže maska událostí (ekvivalentní poll.modify(obj, 0)), takže pro něj nejsou hlášeny žádné další události, dokud jeho maska není znovu nastavena pomocí modify().

Je zaručeno, že všechny čekající naplánované callbacky se spustí před vstupem do dotazovací smyčky.

Rozdíl oproti CPythonu

Tato metoda je rozšíření MicroPythonu.