Асинхронное программирование на Python с помощью asyncio

2
10760
Добавить в избранное

Статья посвящена отважным программистам, которые желают изучать асинхронное программирование на Python с использованием библиотеки asyncio.

Что такое «асинхронность»?

В стандартной (синхронной) программе все инструкции, передаваемые интерпретатору, будут выполняться одна за другой. Такой подход легко визуализировать и предсказать вывод. Но…

Допустим, у вас есть скрипт, который запрашивает данные от трех разных серверов. Иногда выполнение запроса к одному из этих серверов может неожиданно занять слишком много времени. Представьте, что получение данных со второго сервера занимает 10 секунд. Пока вы ждете, весь сценарий фактически ничего не делает.

Что если не дожидаться второго запроса, выполнить третий, а затем вернуться ко второму и продолжит с того места, где он был прерван? Это и будет асинхронный подход – переключение между задачами для минимизации времени простоя.

Тем не менее, асинхронный код можно не использовать, если вам нужен простой скрипт, практически без ввода/вывода (I/O).

Начнем

программирование на Python

Приведем базовые определения основных понятий asyncio:

  • Coroutine (сопрограмма) – генератор, который получает данные, но не генерирует их. В Python 2.5 был введен новый синтаксис, позволяющий отправлять значения генератору. Мы рекомендуем опробовать любопытный курс по сопрограммам для лучшего понимания происходящего.
  • Tasks – планировщики для сопрограмм. Если вы посмотрите на код ниже, то увидите цикл, в котором запускается _step, а он в свою очередь уже вызывает следующий шаг сопрограммы.

  • Event Loop – основное звено asyncio.

Теперь давайте посмотрим, как эта асинхронная связка выполняется в одном потоке:

Асинхронное программирование

 

Как вы можете видеть на схеме:

  • event loop выполняется в потоке;
  • получает данные из очереди;
  • каждая задача вызывает следующий шаг сопрограммы;
  • если сопрограмма вызывает другую сопрограмму (await <имя_сопрограммы>), текущая сопрограмма приостанавливается, и происходит переключение контекста. Контекст текущей сопрограммы (переменные, состояние) сохраняется и загружается контекст вызванной сопрограммы;
  • если сопрограмма встречает блокирующий код (I/O, sleep), текущая сопрограмма приостанавливается, и управление возвращается в event loop;
  • event loop получает следующие задачи из очереди 2, …n;
  • затем event loop возвращается к задаче 1, с которой он был прерван.
Как можно увидеть из примера, асинхронное программирование на Python не отличается от аналогичного программирования на других языках.

Асинхронный vs. синхронный код

async-await

Попробуем доказать, что асинхронный подход действительно работает. Мы сравним два скрипта, которые почти идентичны, кроме метода sleep. В первом используется стандартный time.sleep, а во втором – asyncio.sleep.

Sleep используется здесь, потому что это самый простой способ показать основную идею, как asyncio обрабатывает ввод/вывод.

Здесь используется синхронный sleep внутри async кода:

Вывод:

Теперь тот же код, но с асинхронным методом sleep:

Вывод:

Как видите, асинхронная версия на 2 секунды быстрее. Когда используется асинхронный sleep (каждый раз, когда мы вызываем await asyncio.sleep (1)), управление передается обратно в event loop, который запускает другую задачу из очереди (задачу A или задачу B).

В случае стандартного sleep ничего не происходит: поток простаивает. Фактически, из-за стандартного sleep текущий поток освобождает интерпретатор Python, и он может работать с другими потоками, если они существуют.

Причины использования асинхронного программирования

Такие компании, как Facebook, постоянно используют асинхронное программирование на Python. Например, их программное обеспечение React Native и RocksDB использует асинхронные операции. Кроме того, как Twitter обрабатывает более пяти миллиардов сеансов в день?

Производите рефакторинг кода – это поможет извлечь выгоду из асинхронного подхода, и, как результат, программное обеспечение будет работать быстрее.

Оригинал

Другие материалы по теме:

Интересуетесь программированием на Python?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




2 Комментарии

  1. Я считаю, что это статью от вас давно все ждали, но иногда вы в туторах допускаете ошибки. Помню про git flow у вас в статье были ошибки в командах. Так что господа читайте лучше официальную документацию. Обычно у каждой технологии есть в документации есть раздел «Get started». Вот его и читайте!

Оставьте комментарий