5.1 Event Loop
Teraz krótko dotkniemy drugiej części asynchroniczności, która wszędzie wyskakuje: pętla zdarzeń (Event Loop)
, zadania (Task)
i Future
.
Wyobraź sobie Event Loop jako dyrygenta orkiestry, Task jako muzyków, a Future jako nuty, które muzycy muszą zagrać. Dyrygent (Event Loop) koordynuje pracę muzyków (Task), którzy wykonują muzykę (asynchroniczne operacje), czytając nuty (Future).
Pętla wydarzeń (Event Loop)
jest podstawą programowania asynchronicznego w Python. Odpowiada za wykonywanie zadań asynchronicznych, zarządzanie wydarzeniami i przetwarzanie wejścia-wyjścia. Pętla wydarzeń nieustannie sprawdza, czy są nowe wydarzenia lub zadania i uruchamia je, gdy są gotowe.
Podstawowe funkcje
-
run_forever()
: Uruchamia pętlę wydarzeń i kontynuuje jej wykonywanie, dopóki nie zostanie wywołanestop()
. -
run_until_complete(future)
: Uruchamia pętlę wydarzeń i kończy ją po zakończeniu danego obiektu przyszłego lub korutyny. stop()
: Zatrzymuje pętlę wydarzeń.-
create_task(coroutine)
: Planowanie wykonania korutyny jako zadania.
Przykład użycia:
import asyncio
async def hello():
print("Hello, world!")
await asyncio.sleep(1)
print("Hello again!")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
W tym przykładzie najpierw używamy metody get_event_loop()
, aby uzyskać bieżący obiekt EventLoop
biblioteki asyncio
.
Następnie dodajemy do tego EventLoop
korutynę hello
i prosimy, aby ją wykonał za pomocą metody run_until_complete()
.
W ostatnim kroku zamykamy EventLoop
za pomocą metody close()
.
Przy wykonywaniu tego kodu zobaczysz, że najpierw wyświetli się "Hello, world!", następnie program poczeka 1 sekundę, a potem wyświetli się "Hello again!". To pokazuje, jak Event Loop zarządza wykonaniem asynchronicznej funkcji.
Szczegółowo te działania omówimy na następnym wykładzie.
5.2 Tasks
Zadania (Tasks)
stanowią opakowanie dla korutin, pozwalając zarządzać ich wykonaniem i śledzić ich stan. Zadają pozwalają uruchamiać korutiny równolegle, zarządzając nimi poprzez pętlę wydarzeń.
Tworzenie i zarządzanie zadaniami
-
asyncio.create_task(coroutine)
: Tworzy zadanie do wykonania korutyny. -
Task.result()
: Zwraca wynik zakończonego zadania lub wywołuje wyjątek, jeśli zadanie zakończyło się błędem. Task.cancel()
: Anuluje wykonanie zadania.
Przykład użycia:
import asyncio
async def say_hello():
await asyncio.sleep(1)
print("Hello")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
W tym przykładzie zawijamy korutynę say_hello()
obiektem Task
. Jest on również obiektem asynchronicznym, dlatego aby uzyskać jego wynik, trzeba zastosować do niego operator await
.
Przy wykonywaniu tego kodu program poczeka 1 sekundę, a następnie wyświetli "Hello". To pokazuje, jak Task zarządza wykonaniem korutyny i jak możemy oczekiwać jej zakończenia za pomocą await.
Bardziej szczegółowo o pracy z zadaniami Task
opowiemy na następnym wykładzie.
5.3 Futures
Obiekty Future
reprezentują wynik asynchronicznej operacji, który będzie dostępny w przyszłości. Pozwalają zarządzać stanem asynchronicznej operacji, ustalając wynik lub wyjątek.
Podstawowe metody:
-
set_result(result)
: Ustala wynik dla obiektuFuture
. -
set_exception(exception)
: Ustala wyjątek dla obiektuFuture
. -
result()
: Zwraca wynik obiektuFuture
lub wywołuje wyjątek, jeśli operacja zakończyła się błędem. -
exception()
: Zwraca wyjątek, jeśli został ustalony.
Przykład użycia:
import asyncio
async def set_future(fut, value):
await asyncio.sleep(1)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
await set_future(fut, 'Hello, future!')
print(fut.result())
asyncio.run(main())
W tym przykładzie tworzymy Future, ustalamy jego wartość po sekundzie, a następnie wyświetlamy wynik. Zauważysz, że program poczeka sekundę, zanim wyświetli 'Hello, future!'. To pokazuje, jak Future reprezentuje wynik, który stanie się dostępny w przyszłości.
W przeciwieństwie do obiektu Task
, obiekt Future
jest powiązany z konkretnym Event Loop
, a wykonywana asynchroniczna funkcja może zapisać w nim swój wynik. Chociaż zazwyczaj działa to trochę inaczej.
Zazwyczaj obiekty Future
są używane w połączeniu z zadaniami Task
, które zapewniają wyższy poziom zarządzania asynchronicznymi operacjami.
Teraz po zapoznaniu się z Event Loop
, Task
i Future
, przyjrzymy się im bardziej szczegółowo.
GO TO FULL VERSION