Программирование, управляемое событиями

Программирование, управляемое событиями, фокусируется на событиях. В конце концов, ход программы зависит от событий. До сих пор мы имели дело либо с последовательной, либо с параллельной моделью выполнения, но модель, имеющая концепцию программирования, управляемого событиями, называется асинхронной моделью. Программирование, управляемое событиями, зависит от цикла событий, который всегда ожидает новых входящих событий. Работа событийного программирования зависит от событий. Как только событие зацикливается, события решают, что выполнять и в каком порядке. Следующая блок-схема поможет вам понять, как это работает -

Модуль Python - Asyncio

Модуль Asyncio был добавлен в Python 3.4 и обеспечивает инфраструктуру для написания однопоточного параллельного кода с использованием совместных подпрограмм. Ниже приведены различные концепции, используемые модулем Asyncio.

Цикл событий

Цикл событий - это функция для обработки всех событий в вычислительном коде. Он действует непрерывно во время выполнения всей программы и отслеживает поступление и выполнение событий. Модуль Asyncio допускает один цикл событий для каждого процесса. Ниже приведены некоторые методы, предоставляемые модулем Asyncio для управления циклом событий.

  • loop = get_event_loop() - Этот метод предоставит цикл событий для текущего контекста.

  • loop.call_later(time_delay,callback,argument) - Этот метод организует обратный вызов, который должен быть вызван через заданные секунды time_delay.

  • loop.call_soon(callback,argument)- Этот метод организует обратный вызов, который должен быть вызван как можно скорее. Обратный вызов вызывается после возврата 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 () не принимают аргумент тайм-аута и вызывают исключение, когда будущее еще не сделано.

  • Обратные вызовы, зарегистрированные с помощью 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 в модуле потоковой передачи. Это обобщение концепции подпрограммы. Сопрограмма может быть приостановлена ​​во время выполнения, чтобы она ожидала внешней обработки и возвращалась из точки, в которой она была остановлена, когда внешняя обработка была выполнена. Следующие два способа помогают нам в реализации сопрограмм:

функция async def ()

Это метод реализации сопрограмм в модуле 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 декоратор

Другой метод реализации сопрограмм - использование генераторов с декоратором @ 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.

Ниже приведены пять различных методов класса BaseTransport, которые впоследствии переходят через четыре типа транспорта:

  • close() - Он закрывает транспорт.

  • is_closing() - Этот метод вернет истину, если транспорт закрывается или уже закрыт.

  • get_extra_info(name, default = none) - Это даст нам дополнительную информацию о транспорте.

  • get_protocol() - Этот метод вернет текущий протокол.

Протоколы

Модуль Asyncio предоставляет базовые классы, которые вы можете подклассифицировать для реализации ваших сетевых протоколов. Эти классы используются вместе с транспортами; протокол анализирует входящие данные и запрашивает запись исходящих данных, в то время как транспорт отвечает за фактический ввод-вывод и буферизацию. Ниже приведены три класса протокола -

  • Protocol - Это базовый класс для реализации потоковых протоколов для использования с транспортом TCP и SSL.

  • DatagramProtocol - Это базовый класс для реализации протоколов дейтаграмм для использования с транспортом UDP.

  • SubprocessProtocol - Это базовый класс для реализации протоколов, взаимодействующих с дочерними процессами через набор однонаправленных каналов.