asyncio — asynchroniczny harmonogram operacji we/wy

Ten moduł udostępnia harmonogram kooperacyjnej wielozadaniowości dla coroutin async/await, wraz z prymitywami do synchronizacji (blokady, zdarzenia) oraz nieblokującą obsługą sieci TCP poprzez czytniki i zapisywacze strumieni. Zadania są wykonywane współbieżnie w pojedynczej pętli zdarzeń; aktualnie wykonywane zadanie oddaje sterowanie z powrotem do pętli za pomocą await.

Przykład:

import asyncio

async def blink(led, period_ms):
    while True:
        led.on()
        await asyncio.sleep_ms(5)
        led.off()
        await asyncio.sleep_ms(period_ms)

async def main(led1, led2):
    asyncio.create_task(blink(led1, 700))
    asyncio.create_task(blink(led2, 400))
    await asyncio.sleep_ms(10_000)

# Running on an OpenMV Cam
from machine import LED
asyncio.run(main(LED(1), LED(2)))

Funkcje podstawowe

asyncio.create_task(coro: Coroutine) Task

Tworzy nowe zadanie z podanej coroutiny i planuje jego wykonanie.

Zwraca odpowiadający obiekt Task.

asyncio.current_task() Task

Zwraca obiekt Task powiązany z aktualnie wykonywanym zadaniem.

asyncio.run(coro: Coroutine) Any

Tworzy nowe zadanie z podanej coroutiny i wykonuje je aż do zakończenia.

Zwraca wartość zwróconą przez coro.

asyncio.sleep(t: float) None

Usypia na t sekund (może być wartością zmiennoprzecinkową).

To jest coroutina.

asyncio.sleep_ms(t: int) None

Usypia na t milisekund.

To jest coroutina oraz rozszerzenie MicroPython.

Funkcje dodatkowe

asyncio.wait_for(awaitable: Awaitable, timeout: float) Any

Czeka na zakończenie awaitable, ale anuluje je, jeśli trwa dłużej niż timeout sekund. Jeśli awaitable nie jest zadaniem, zostanie z niego utworzone zadanie.

Jeśli wystąpi przekroczenie czasu, anuluje zadanie i zgłasza asyncio.TimeoutError: powinno to zostać przechwycone przez wywołującego. Zadanie otrzymuje asyncio.CancelledError, który może zostać zignorowany lub przechwycony za pomocą try...except albo try...finally w celu wykonania kodu sprzątającego.

Zwraca wartość zwracaną przez awaitable.

To jest coroutina.

asyncio.wait_for_ms(awaitable: Awaitable, timeout: int) Any

Podobne do wait_for(), ale timeout jest liczbą całkowitą wyrażoną w milisekundach.

To jest coroutina oraz rozszerzenie MicroPython.

asyncio.gather(*awaitables, return_exceptions: bool = False) List

Wykonuje wszystkie awaitables współbieżnie. Wszystkie awaitables, które nie są zadaniami, zostają awansowane na zadania.

Zwraca listę wartości zwracanych przez wszystkie awaitables.

To jest coroutina.

class Task

class asyncio.Task

Ten obiekt opakowuje coroutinę w wykonywane zadanie. Na zadania można oczekiwać za pomocą await task, co spowoduje oczekiwanie na zakończenie zadania i zwrócenie jego wartości.

Zadań nie należy tworzyć bezpośrednio, lecz używać do tego create_task().

cancel() None

Anuluje zadanie poprzez wstrzyknięcie do niego asyncio.CancelledError. Zadanie może zignorować ten wyjątek. Kod sprzątający można wykonać, przechwytując go, lub za pomocą try ... finally.

class Event

class asyncio.Event

Tworzy nowe zdarzenie, które można wykorzystać do synchronizacji zadań. Zdarzenia rozpoczynają w stanie wyczyszczonym.

is_set() bool

Zwraca True, jeśli zdarzenie jest ustawione, w przeciwnym razie False.

set() None

Ustawia zdarzenie. Wszystkie zadania oczekujące na to zdarzenie zostaną zaplanowane do wykonania.

Uwaga: musi to być wywołane z wnętrza zadania. Nie jest bezpieczne wywoływanie tego z IRQ, wywołania zwrotnego harmonogramu ani innego wątku. Zobacz ThreadSafeFlag.

clear() None

Czyści zdarzenie.

wait() None

Czeka na ustawienie zdarzenia. Jeśli zdarzenie jest już ustawione, zwraca natychmiast.

To jest coroutina.

class ThreadSafeFlag

class asyncio.ThreadSafeFlag

Tworzy nową flagę, której można użyć do synchronizacji zadania z kodem wykonywanym poza pętlą asyncio, takim jak inne wątki, IRQ lub wywołania zwrotne harmonogramu. Flagi rozpoczynają w stanie wyczyszczonym.

set() None

Ustawia flagę. Jeśli istnieje zadanie oczekujące na flagę, zostanie ono zaplanowane do wykonania.

clear() None

Czyści flagę. Można to wykorzystać, aby upewnić się, że ewentualnie wcześniej ustawiona flaga jest wyczyszczona przed oczekiwaniem na nią.

wait() None

Czeka na ustawienie flagi. Jeśli flaga jest już ustawiona, zwraca natychmiast. Flaga jest automatycznie resetowana po powrocie z wait.

Na flagę może oczekiwać jednocześnie tylko jedno zadanie.

To jest coroutina.

class Lock

class asyncio.Lock

Tworzy nową blokadę, której można użyć do koordynacji zadań. Blokady rozpoczynają w stanie odblokowanym.

Oprócz poniższych metod, blokad można używać w instrukcji async with.

locked() bool

Zwraca True, jeśli blokada jest zablokowana, w przeciwnym razie False.

acquire() bool

Czeka, aż blokada znajdzie się w stanie odblokowanym, a następnie blokuje ją w sposób atomowy. W danym momencie tylko jedno zadanie może uzyskać blokadę.

To jest coroutina.

release() None

Zwalnia blokadę. Jeśli jakieś zadania oczekują na blokadę, następne z kolejki zostaje zaplanowane do wykonania, a blokada pozostaje zablokowana. W przeciwnym razie żadne zadania nie oczekują i blokada zostaje odblokowana.

Połączenia strumieniowe TCP

asyncio.open_connection(host: str, port: int, ssl: ssl.SSLContext | bool | None = None) Tuple[Stream, Stream]

Otwiera połączenie TCP z podanym host i port. Adres host zostanie rozwiązany za pomocą socket.getaddrinfo(), które jest obecnie wywołaniem blokującym. Jeśli ssl jest obiektem ssl.SSLContext, kontekst ten jest używany do utworzenia transportu; jeśli ssl ma wartość True, używany jest kontekst domyślny.

Zwraca parę strumieni: strumień czytnika i strumień zapisywacza. Zgłosi specyficzny dla gniazda OSError, jeśli host nie mógł zostać rozwiązany lub jeśli nie udało się nawiązać połączenia.

To jest coroutina.

asyncio.start_server(callback: Callable, host: str, port: int, backlog: int = 5, ssl: ssl.SSLContext | None = None) Server

Uruchamia serwer TCP na podanym host i port. Funkcja callback zostanie wywołana dla przychodzących, zaakceptowanych połączeń i otrzyma 2 argumenty: strumienie czytnika i zapisywacza dla danego połączenia.

Jeśli ssl jest obiektem ssl.SSLContext, kontekst ten jest używany do utworzenia transportu.

Zwraca obiekt Server.

To jest coroutina.

class asyncio.Stream

Reprezentuje połączenie strumieniowe TCP. Aby zminimalizować ilość kodu, ta klasa implementuje zarówno czytnik, jak i zapisywacz, a zarówno StreamReader, jak i StreamWriter są aliasami tej klasy.

get_extra_info(v: str) Any

Pobiera dodatkowe informacje o strumieniu, określone przez v. Prawidłowe wartości dla v to: peername.

close() None

Zamyka strumień.

wait_closed() None

Czeka na zamknięcie strumienia.

To jest coroutina.

read(n: int = -1) bytes

Odczytuje do n bajtów i zwraca je. Jeśli n nie zostanie podane lub wynosi -1, odczytuje wszystkie bajty aż do EOF. Zwrócona wartość będzie pustym obiektem bytes, jeśli EOF zostanie napotkany przed odczytaniem jakichkolwiek bajtów.

To jest coroutina.

readinto(buf: bytearray | memoryview) int

Odczytuje do n bajtów do buf, gdzie n jest równe długości buf.

Zwraca liczbę bajtów odczytanych do buf.

To jest coroutina oraz rozszerzenie MicroPython.

readexactly(n: int) bytes

Odczytuje dokładnie n bajtów i zwraca je jako obiekt bytes.

Zgłasza wyjątek EOFError, jeśli strumień kończy się przed odczytaniem n bajtów.

To jest coroutina.

readline() bytes

Odczytuje wiersz i zwraca go.

To jest coroutina.

write(buf: bytes) None

Dołącza buf do bufora wyjściowego. Dane są opróżniane dopiero po wywołaniu Stream.drain(). Zaleca się wywołanie Stream.drain() bezpośrednio po wywołaniu tej funkcji.

drain() None

Opróżnia (zapisuje) wszystkie zbuforowane dane wyjściowe do strumienia.

To jest coroutina.

class asyncio.Server

Reprezentuje klasę serwera zwracaną przez start_server(). Można jej używać w instrukcji async with, aby zamknąć serwer przy wyjściu.

close() None

Zamyka serwer.

wait_closed() None

Czeka na zamknięcie serwera.

To jest coroutina.

Pętla zdarzeń

asyncio.get_event_loop() Loop

Zwraca pętlę zdarzeń używaną do planowania i wykonywania zadań. Zobacz Loop.

asyncio.new_event_loop() Loop

Resetuje pętlę zdarzeń i zwraca ją.

Uwaga: ponieważ MicroPython ma tylko jedną pętlę zdarzeń, funkcja ta jedynie resetuje stan pętli, nie tworzy nowej.

class asyncio.Loop

Reprezentuje obiekt, który planuje i wykonuje zadania. Nie można go utworzyć, zamiast tego należy użyć get_event_loop().

create_task(coro: Coroutine) Task

Tworzy zadanie z podanego coro i zwraca nowy obiekt Task.

run_forever() None

Wykonuje pętlę zdarzeń aż do wywołania stop().

run_until_complete(awaitable: Awaitable) Any

Wykonuje podane awaitable aż do jego zakończenia. Jeśli awaitable nie jest zadaniem, zostanie awansowane na zadanie.

stop() None

Zatrzymuje pętlę zdarzeń.

close() None

Zamyka pętlę zdarzeń.

set_exception_handler(handler: Callable) None

Ustawia procedurę obsługi wyjątków wywoływaną, gdy zadanie zgłosi wyjątek, który nie zostanie przechwycony. Funkcja handler powinna przyjmować dwa argumenty: (loop, context).

get_exception_handler() Callable | None

Pobiera bieżącą procedurę obsługi wyjątków. Zwraca procedurę obsługi lub None, jeśli nie ustawiono niestandardowej procedury.

default_exception_handler(context: dict) None

Domyślna procedura obsługi wyjątków, która jest wywoływana.

call_exception_handler(context: dict) None

Wywołuje bieżącą procedurę obsługi wyjątków. Argument context jest przekazywany i jest słownikiem zawierającym klucze: 'message', 'exception', 'future'.