Событийное программирование фокусируется на событиях. В конце концов, поток программы зависит от событий. До сих пор мы имели дело либо с последовательной, либо с параллельной моделью выполнения, но модель, имеющую концепцию управляемого событиями программирования, называется асинхронной моделью. Программирование, управляемое событиями, зависит от цикла событий, который всегда прослушивает новые входящие события. Работа программирования, управляемого событиями, зависит от событий. Как только событие зацикливается, события решают, что и в каком порядке выполнять. Следующая блок-схема поможет вам понять, как это работает —
Модуль Python — Asyncio
Модуль Asyncio был добавлен в Python 3.4 и предоставляет инфраструктуру для написания однопоточного параллельного кода с использованием сопрограмм. Ниже приведены различные концепции, используемые модулем Asyncio.
Цикл событий
Event-loop — это функциональность для обработки всех событий в вычислительном коде. Он действует во время выполнения всей программы и отслеживает входящие и выполняемые события. Модуль Asyncio допускает один цикл обработки событий для каждого процесса. Ниже приведены некоторые методы, предоставляемые модулем Asyncio для управления циклом событий:
-
loop = get_event_loop () — Этот метод предоставит цикл обработки событий для текущего контекста.
-
loop.call_later (time_delay, callback, аргумент) — этот метод организует обратный вызов, который должен быть вызван после заданных секунд time_delay.
-
loop.call_soon (callback, аргумент) — этот метод организует обратный вызов, который должен быть вызван как можно скорее. Обратный вызов вызывается после возврата call_soon () и когда элемент управления возвращается в цикл обработки событий.
-
loop.time () — Этот метод используется для возврата текущего времени в соответствии с внутренними часами цикла событий.
-
asyncio.set_event_loop () — этот метод устанавливает цикл обработки событий для текущего контекста в цикл.
-
asyncio.new_event_loop () — этот метод создает и возвращает новый объект цикла событий.
-
loop.run_forever () — этот метод будет работать до тех пор, пока не будет вызван метод stop ().
loop = get_event_loop () — Этот метод предоставит цикл обработки событий для текущего контекста.
loop.call_later (time_delay, callback, аргумент) — этот метод организует обратный вызов, который должен быть вызван после заданных секунд time_delay.
loop.call_soon (callback, аргумент) — этот метод организует обратный вызов, который должен быть вызван как можно скорее. Обратный вызов вызывается после возврата call_soon () и когда элемент управления возвращается в цикл обработки событий.
loop.time () — Этот метод используется для возврата текущего времени в соответствии с внутренними часами цикла событий.
asyncio.set_event_loop () — этот метод устанавливает цикл обработки событий для текущего контекста в цикл.
asyncio.new_event_loop () — этот метод создает и возвращает новый объект цикла событий.
loop.run_forever () — этот метод будет работать до тех пор, пока не будет вызван метод stop ().
пример
Следующий пример цикла обработки событий помогает в печати hello world с помощью метода get_event_loop (). Этот пример взят из официальных документов Python.
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()
Выход
Hello World
фьючерсы
Это совместимо с классом concurrent.futures.Future, который представляет вычисление, которое не было выполнено. Существуют следующие различия между asyncio.futures.Future и concurrent.futures.Future —
-
Методы result () и exception () не принимают аргумент timeout и вызывают исключение, когда будущее еще не сделано.
-
Обратные вызовы, зарегистрированные с помощью add_done_callback (), всегда вызываются через call_soon () цикла обработки событий.
-
Класс asyncio.futures.Future не совместим с функциями wait () и as_completed () в пакете concurrent.futures.
Методы result () и exception () не принимают аргумент timeout и вызывают исключение, когда будущее еще не сделано.
Обратные вызовы, зарегистрированные с помощью add_done_callback (), всегда вызываются через call_soon () цикла обработки событий.
Класс asyncio.futures.Future не совместим с функциями wait () и as_completed () в пакете concurrent.futures.
пример
Ниже приведен пример, который поможет вам понять, как использовать класс 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()
Выход
Future Completed
Сопрограммы
Концепция сопрограмм в Asyncio аналогична концепции стандартного объекта Thread в модуле Threading. Это обобщение концепции подпрограммы. Сопрограмма может быть приостановлена во время выполнения, чтобы она ожидала внешней обработки и возвращалась из точки, в которой она была остановлена, когда была выполнена внешняя обработка. Следующие два способа помогают нам в реализации сопрограмм —
функция асинхронной защиты ()
Это метод реализации сопрограмм в модуле Asyncio. Ниже приводится сценарий Python для того же самого —
import asyncio async def Myoperation(): print("First Coroutine") loop = asyncio.get_event_loop() try: loop.run_until_complete(Myoperation()) finally: loop.close()
Выход
First Coroutine
@ asyncio.coroutine decorator
Другой способ реализации сопрограмм — использование генераторов с декоратором @ asyncio.coroutine. Ниже приводится сценарий Python для того же самого —
import asyncio @asyncio.coroutine def Myoperation(): print("First Coroutine") loop = asyncio.get_event_loop() try: loop.run_until_complete(Myoperation()) finally: loop.close()
Выход
First Coroutine
Задачи
Этот подкласс модуля Asyncio отвечает за параллельное выполнение сопрограмм в цикле событий. Следующий скрипт Python является примером параллельной обработки некоторых задач.
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()
Выход
Tasks Completed Processing 0 Processing 1 Processing 2 Processing 3 Processing 4 Processing 5 Processing 6 Processing 7 Processing 8 Processing 9
Транспорты
Модуль Asyncio предоставляет транспортные классы для реализации различных типов связи. Эти классы не являются поточно-ориентированными и всегда связаны с экземпляром протокола после установления канала связи.
Ниже приведены различные типы транспорта, унаследованные от BaseTransport —
-
ReadTransport — это интерфейс для транспортов только для чтения.
-
WriteTransport — это интерфейс для транспорта только для записи.
-
DatagramTransport — это интерфейс для отправки данных.
-
BaseSubprocessTransport — аналогично классу BaseTransport.
ReadTransport — это интерфейс для транспортов только для чтения.
WriteTransport — это интерфейс для транспорта только для записи.
DatagramTransport — это интерфейс для отправки данных.
BaseSubprocessTransport — аналогично классу BaseTransport.
Далее следуют пять различных методов класса BaseTransport, которые впоследствии переходят между четырьмя типами транспорта:
-
close () — закрывает транспорт.
-
is_closing () — Этот метод вернет true, если транспорт закрывается или уже закрыт.transports.
-
get_extra_info (name, default = none) — это даст нам дополнительную информацию о транспорте.
-
get_protocol () — Этот метод возвращает текущий протокол.
close () — закрывает транспорт.
is_closing () — Этот метод вернет true, если транспорт закрывается или уже закрыт.transports.
get_extra_info (name, default = none) — это даст нам дополнительную информацию о транспорте.
get_protocol () — Этот метод возвращает текущий протокол.
протоколы
Модуль Asyncio предоставляет базовые классы, которые вы можете подклассить для реализации ваших сетевых протоколов. Эти классы используются вместе с транспортом; протокол анализирует входящие данные и запрашивает запись исходящих данных, в то время как транспорт отвечает за фактический ввод-вывод и буферизацию. Ниже приведены три класса протокола —
Протокол — это базовый класс для реализации потоковых протоколов для использования с транспортными средствами TCP и SSL.
DatagramProtocol — это базовый класс для реализации протоколов дейтаграмм для использования с транспортами UDP.
SubprocessProtocol — это базовый класс для реализации протоколов, взаимодействующих с дочерними процессами через набор однонаправленных каналов.