Programowanie sterowane zdarzeniami
Programowanie sterowane zdarzeniami koncentruje się na wydarzeniach. Ostatecznie przebieg programu zależy od wydarzeń. Do tej pory mieliśmy do czynienia z sekwencyjnym lub równoległym modelem wykonania, ale model mający koncepcję programowania sterowanego zdarzeniami nazywany jest modelem asynchronicznym. Programowanie sterowane zdarzeniami zależy od pętli zdarzeń, która zawsze nasłuchuje nowych nadchodzących zdarzeń. Działanie programowania sterowanego zdarzeniami zależy od zdarzeń. Po zapętleniu zdarzenia decydują o tym, co i w jakiej kolejności wykonać. Poniższy schemat blokowy pomoże Ci zrozumieć, jak to działa -
Moduł Pythona - Asyncio
Moduł Asyncio został dodany w Pythonie 3.4 i zapewnia infrastrukturę do pisania jednowątkowego kodu współbieżnego przy użyciu współprogramów. Poniżej przedstawiono różne koncepcje używane przez moduł Asyncio -
Pętla zdarzeń
Pętla zdarzeń to funkcja obsługująca wszystkie zdarzenia w kodzie obliczeniowym. Działa na okrągło podczas wykonywania całego programu i śledzi przychodzące i wykonywane zdarzenia. Moduł Asyncio umożliwia pojedynczą pętlę zdarzeń na proces. Poniżej znajduje się kilka metod zapewnianych przez moduł Asyncio do zarządzania pętlą zdarzeń -
loop = get_event_loop() - Ta metoda zapewni pętlę zdarzeń dla bieżącego kontekstu.
loop.call_later(time_delay,callback,argument) - Ta metoda organizuje wywołanie zwrotne, które ma zostać wywołane po podanych sekundach time_delay.
loop.call_soon(callback,argument)- Ta metoda zapewnia wywołanie zwrotne tak szybko, jak to możliwe. Wywołanie zwrotne jest wywoływane po powrocie funkcji call_soon () i po powrocie sterowania do pętli zdarzeń.
loop.time() - Ta metoda służy do zwracania aktualnego czasu zgodnie z wewnętrznym zegarem pętli zdarzeń.
asyncio.set_event_loop() - Ta metoda ustawi pętlę zdarzeń dla bieżącego kontekstu na pętlę.
asyncio.new_event_loop() - Ta metoda utworzy i zwróci nowy obiekt pętli zdarzeń.
loop.run_forever() - Ta metoda będzie działać do momentu wywołania metody stop ().
Przykład
Poniższy przykład pętli zdarzeń pomaga w drukowaniu hello worldużywając metody get_event_loop (). Ten przykład pochodzi z oficjalnej dokumentacji Pythona.
import asyncio
def hello_world(loop):
print('Hello World')
loop.stop()
loop = asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
loop.close()
Wynik
Hello World
Futures
Jest to zgodne z klasą concurrent.futures.Future, która reprezentuje obliczenia, które nie zostały wykonane. Istnieją następujące różnice między asyncio.futures.Future i concurrent.futures.Future -
metody result () iception () nie pobierają argumentu timeout i zgłaszają wyjątek, gdy przyszłość nie jest jeszcze wykonana.
Wywołania zwrotne zarejestrowane za pomocą add_done_callback () są zawsze wywoływane za pośrednictwem funkcji call_soon () pętli zdarzeń.
Klasa asyncio.futures.Future nie jest zgodna z funkcjami wait () i as_completed () w pakiecie concurrent.futures.
Przykład
Poniżej znajduje się przykład, który pomoże ci zrozumieć, jak używać klasy asyncio.futures.future.
import asyncio
async def Myoperation(future):
await asyncio.sleep(2)
future.set_result('Future Completed')
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
loop.run_until_complete(future)
print(future.result())
finally:
loop.close()
Wynik
Future Completed
Coroutines
Koncepcja coroutines w Asyncio jest podobna do koncepcji standardowego obiektu Thread w module Threading. To jest uogólnienie koncepcji podprogramów. Program może zostać zawieszony w trakcie wykonywania, aby czekał na przetwarzanie zewnętrzne i wrócił z miejsca, w którym został zatrzymany, gdy przetwarzanie zewnętrzne zostało zakończone. Poniższe dwa sposoby pomagają nam we wdrażaniu programów -
async def, funkcja ()
Jest to metoda implementacji coroutines w module Asyncio. Poniżej znajduje się skrypt w Pythonie dla tego samego -
import asyncio
async def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Wynik
First Coroutine
@ asyncio.coroutine dekorator
Inną metodą implementacji coroutines jest wykorzystanie generatorów z dekoratorem @ asyncio.coroutine. Poniżej znajduje się skrypt w Pythonie dla tego samego -
import asyncio
@asyncio.coroutine
def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Wynik
First Coroutine
Zadania
Ta podklasa modułu Asyncio jest odpowiedzialna za równoległe wykonywanie procedur w pętli zdarzeń. Poniższy skrypt w Pythonie jest przykładem równoległego przetwarzania niektórych zadań.
import asyncio
import time
async def Task_ex(n):
time.sleep(1)
print("Processing {}".format(n))
async def Generator_task():
for i in range(10):
asyncio.ensure_future(Task_ex(i))
int("Tasks Completed")
asyncio.sleep(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()
Wynik
Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9
Transporty
Moduł Asyncio udostępnia klasy transportowe do realizacji różnego rodzaju komunikacji. Te klasy nie są bezpieczne dla wątków i zawsze są sparowane z instancją protokołu po ustanowieniu kanału komunikacyjnego.
Poniżej przedstawiono różne typy transportów odziedziczone po BaseTransport -
ReadTransport - To jest interfejs dla transportów tylko do odczytu.
WriteTransport - To jest interfejs dla transportów tylko do zapisu.
DatagramTransport - To jest interfejs do wysyłania danych.
BaseSubprocessTransport - Podobny do klasy BaseTransport.
Poniżej znajduje się pięć różnych metod klasy BaseTransport, które są następnie przejściowe dla czterech typów transportu -
close() - To zamyka transport.
is_closing() - Ta metoda zwróci wartość true, jeśli transport się zamyka lub jest już zamknięty.
get_extra_info(name, default = none) - To da nam dodatkowe informacje o transporcie.
get_protocol() - Ta metoda zwróci bieżący protokół.
Protokoły
Moduł Asyncio udostępnia klasy bazowe, które można podklasować w celu zaimplementowania protokołów sieciowych. Klasy te są używane w połączeniu z transportami; protokół analizuje przychodzące dane i prosi o zapis danych wychodzących, podczas gdy transport jest odpowiedzialny za faktyczne I / O i buforowanie. Poniżej przedstawiono trzy klasy protokołu -
Protocol - Jest to klasa bazowa do implementowania protokołów przesyłania strumieniowego do użytku z transportami TCP i SSL.
DatagramProtocol - To jest klasa bazowa do implementowania protokołów datagramów do użytku z transportami UDP.
SubprocessProtocol - Jest to klasa bazowa do implementowania protokołów komunikujących się z procesami potomnymi za pośrednictwem zestawu potoków jednokierunkowych.