6.1 Uzyskanie cyklu wydarzeń
Cykl wydarzeń (Event Loop)
jest centralnym elementem w programowaniu asynchronicznym z wykorzystaniem modułu asyncio w Python. Zarządza wykonaniem zadań asynchronicznych, obsługą wydarzeń i operacjami wejścia-wyjścia. Cykl wydarzeń pozwala kilku zadaniom wykonywać się jednocześnie, nie blokując głównego wątku wykonania.
Tworzenie i uzyskiwanie cyklu wydarzeń
-
asyncio.get_event_loop()
: Zwraca aktualny cykl wydarzeń lub tworzy nowy, jeśli aktualnego nie ma. -
asyncio.new_event_loop()
: Tworzy nowy cykl wydarzeń. -
asyncio.set_event_loop(loop)
: Ustawia podany cykl wydarzeń jako aktualny.
Przykład:
asyncio posiada aktualny cykl wydarzeń, który zawiera wszystkie wykonywane zadania. Możesz uzyskać aktualny cykl wydarzeń lub stworzyć nowy i ustawić go jako aktualny. Co dzieje się w poniższym przykładzie.
import asyncio
loop = asyncio.get_event_loop()
print(loop) # Aktualny cykl wydarzeń
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # Nowo ustawiony cykl wydarzeń
Warto zauważyć, że metoda get_event_loop()
zwraca aktualny aktywny cykl wydarzeń. Tworzenie nowego cyklu wydarzeń i jego ustawienie powinno być używane ostrożnie, aby uniknąć konfliktów w aplikacjach asynchronicznych.
Uruchamianie cyklu wydarzeń
-
run_forever()
: Uruchamia cykl wydarzeń i kontynuuje jego wykonywanie do momentu wywołaniastop()
. -
run_until_complete(future)
: Uruchamia cykl wydarzeń i kończy go po zakończeniu zadanej korutyny lub obiektu future.
Przykład:
Cykl wydarzeń można uruchomić w dwóch trybach: pracować bez końca — coś w rodzaju while True
, albo do momentu wykonania konkretnego zadania.
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1)
print("World")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
Jeśli uruchomiłeś Event Loop
w trybie run_forever()
, będzie kręcił wewnątrz siebie cykl bez końca. Metoda run_forever()
zakończy pracę tylko jeśli jakieś asynchroniczne zadanie wywoła u naszego EventLoop
metodę stop()
.
Zatrzymywanie cyklu wydarzeń
stop()
: Zatrzymuje cykl wydarzeń.-
is_running()
: ZwracaTrue
, jeśli cykl wydarzeń jest uruchomiony.
Przykład:
Jeśli cykl jest uruchomiony w trybie bez końca, stale odbiera zadania i je wykonuje, to sam się nie zatrzyma. Ktoś musi uzyskać obiekt naszego aktualnego cyklu i wywołać u niego metodę stop()
. Żeby dowiedzieć się, czy cykl działa bez końca, należy wywołać metodę is_running()
.
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 Ważne metody cyklu wydarzeń
Metoda call_soon(callback, *args)
Planuje wywołanie funkcji callback
z argumentami *args
tak szybko, jak to możliwe.
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
Umieszcza funkcję callback
na samym początku listy zadań, aby mogła rozpocząć się jak najszybciej. Do metody można przekazywać funkcje nieasynchroniczne. Ta metoda jest przydatna, gdy trzeba wykonać zadanie z minimalnym opóźnieniem, szczególnie gdy wymagana jest natychmiastowa reakcja w aplikacji asynchronicznej.
Metoda call_later(delay, callback, *args)
Planuje wywołanie funkcji callback
z argumentami *args
po opóźnieniu delay
sekund.
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
Ta metoda pozwala na wykonanie odłożonego wywołania funkcji: pierwszym parametrem przekazywane jest opóźnienie w sekundach (może być ułamkowe), a dalej — odnośnik do funkcji i jej parametry. Do metody można przekazywać funkcje nieasynchroniczne. Ta metoda może być używana do zarządzania wykonywaniem zadań o różnym stopniu pilności, co jest przydatne przy projektowaniu złożonych systemów asynchronicznych.
Metoda call_at(when, callback, *args)
Planuje wywołanie funkcji callback
z argumentami *args
w momencie czasu when
.
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # Za 2 sekundy od aktualnego czasu cyklu wydarzeń
loop.call_at(when, my_callback)
loop.run_forever()
Jeśli chcesz uruchomić zadanie nie za 5 sekund, ale na przykład o 15:00 lub 24:00, to wygodniej będzie skorzystać z funkcji call_at()
, która działa tak samo, jak funkcja call_soon()
, ale pierwszym parametrem w niej przekazywany jest nie czas trwania pauzy, ale czas, w którym należy wywołać zadaną funkcję. Do metody można przekazywać funkcje nieasynchroniczne.
Zalety i cechy
Asynchroniczne wykonanie: Cykl wydarzeń pozwala wykonywać wiele zadań równolegle, nie blokując głównego wątku wykonania.
Efektywne zarządzanie zasobami: Asynchroniczne operacje wejścia-wyjścia wykonywane są bez blokowania, co sprawia, że programy są bardziej efektywne.
Elastyczność i skalowalność: Cykl wydarzeń obsługuje wiele metod do planowania zadań i obsługi wydarzeń, co pozwala tworzyć złożone i skalowalne aplikacje asynchroniczne.
6.3 Interakcja z zadaniami i obiektami future
Cykl wydarzeń zarządza wykonaniem zadań (Tasks) i obiektów future. Śledzi ich stan i zapewnia ich wykonanie w miarę gotowości.
Przykład:
import asyncio
async def main():
await asyncio.sleep(1)
print("Task completed")
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)
W tym przykładzie pokazano, jak cykl wydarzeń zarządza wykonaniem zadania, stworzonego za pomocą metody create_task
. Metody call_soon()
, call_later()
i call_at()
można używać do zarządzania wykonywaniem zadań o różnym stopniu pilności, co jest przydatne przy projektowaniu złożonych systemów asynchronicznych.
GO TO FULL VERSION