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