Что такое асинхронное программирование python
Перейти к содержимому

Что такое асинхронное программирование python

  • автор:

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

Ассинхроность дает нам плюс к многозадачности.Даваете посмотрим два примера кода:

import time def start(): print(1) def time(): time.sleep(20) print(2) def end(): print(3) def main(): start_time = time.time() start() time() end() end_time = time.time() elapsed_time = end_time — start_time print(f»Elapsed time: seconds») if __name__ == «__main__»: main()

И с ассинхроностью:

import asyncio import time async def start(): print(1) async def time(): await asyncio.sleep(20) print(2) def end(): print(3) async def main(): start_time = time.time() await start() await time() end() end_time = time.time() elapsed_time = end_time — start_time print(f»Elapsed time: seconds») if __name__ == «__main__»: asyncio.run(main())

Здесь скорость двух примеров относительна близка,но в больших проектах лучше использовать ассинхроность.

Теперь переидем к обьяснению:

Асинхронность (асинхронное программирование) в программировании означает выполнение задач без явного ожидания завершения предыдущих задач. Вместо того, чтобы блокировать выполнение программы при ожидании завершения операции, асинхронный код позволяет программе продолжать работу и выполнять другие задачи во время ожидания.

import asyncio async def task1(): print(«Task 1 started») await asyncio.sleep(2) # Имитируем длительную операцию print(«Task 1 completed») async def task2(): print(«Task 2 started») await asyncio.sleep(1) # Имитируем длительную операцию print(«Task 2 completed») async def main(): print(«Main started») await asyncio.gather(task1(), task2()) # Запускаем задачи параллельно print(«Main completed») asyncio.run(main())

В этом примере мы используем модуль asyncio для создания асинхронной программы. Есть две асинхронные задачи task1() и task2(), которые имитируют длительные операции, используя await asyncio.sleep() для приостановки выполнения на определенное время.

Функция main() является точкой входа в программу и запускает задачи task1() и task2() параллельно с помощью asyncio.gather(). Важно отметить, что когда одна из задач ожидает (await), другая задача может продолжить выполнение, не блокируя программу.

Выполнение кода показывает, что «Task 1 started» и «Task 2 started» выводятся одновременно, а затем после задержки «Task 2 completed» выводится раньше, чем «Task 1 completed». Это демонстрирует параллельное выполнение асинхронных задач.

Асинхронность позволяет эффективно использовать ресурсы и повышает отзывчивость программы, особенно когда есть операции ввода-вывода (I/O), такие как чтение из сети или запись на диск. Вместо блокировки выполнения при ожидании I/O операций, асинхронный код может переключаться между задачами, позволяя другим задачам продолжать выполнение.

Обратите внимание, что для запуска асинхронной программы мы используем asyncio.run(main()), которая создает цикл событий asyncio и запускает функцию main() в этом цикле событий.

Спасибо за просмотр статьй.

Зачем нужна асинхронность

Бекенд-разработчики обычно пишут синхронный код. В нём команды исполняются одна за другой:

# . grand_total = sum(cart_products.values()) print(grand_total) # . 

Ничего не требуется предпринимать, если синхронный код работает быстро. Проблемы возникают, когда он подвисает и не реагирует на команды пользователя. Синхронный email-клиент не сможет реагировать на нажатие кнопок, пока он скачивает почту. А скачивание тоже происходит синхронно: пока не ответит первый email-провайдер, клиент не отправит запрос второму.

Асинхронное программирование позволяет сделать несколько быстрых действий, пока не завершится долгое. Email-клиент может показывать пользователю скачанные письма, пока новая почта асинхронно загружается. Вот как это выглядит в псевдокоде:

while True: download_progress = download_emails_step_by_step(download_progress) click = read_click() # . 

Асинхронным этот код делает функция, которая названа download_emails_step_by_step . Она скачивает не всю почту за раз, а понемногу. Скачав кусочек, она возвращает управление циклу while True . Этот цикл дальше запустит read_click , которая вернёт клик пользователя, если он был, и None , если не было. Другие функции в этом цикле аналогичные: они делают небольшое действие, останавливаются, возвращают управление циклу, который их снова запускает позже.

Обычные функции в Питоне работают не так, как это принято в асинхронном программировании. Функция input , например, ждёт пользовательского ввода и может долго не возвращать управление вызвавшему её коду. Поэтому в язык добавили библиотеку asyncio, которая содержит инструменты для работы с асинхронным кодом и асинхронные эквиваленты синхронных функций (например, sleep).

Привычные инструменты ломают асинхронный код

Рассмотрим ещё один пример. Есть сервер, который возвращает координаты перемещения автобусов в реальном времени. Для каждого автобуса ведётся трансляция его координат. Асинхронный код поможет отрисовать маршрут движения автобуса до того, как закончится трансляция координат. Нам не обязательно даже знать, закончится ли она, потому что данные обрабатываются по частям, небольшими порциями.

Асинхронный код подходит всегда, когда есть несколько потоков ввода, и достаточно обработать только часть данных, но быстро и одновременно у всех потоков. Для решения этого класса задач и нужен асинхронный Python.

Если потоков данных много, то спасет асинхронность

Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

Что такое асинхронность в Python и как ее правильно применять

Моё мнение про Python

Основные аспекты изучения Python

Самые популярные библиотеки Python

Что должен знать Junior Python разработчик для устройства на работу

Среда разработки для Python: что это, какие они бывают и как их использовать

Асинхронность в Python — это концепция программирования, которая позволяет выполнять задачи независимо друг от друга, без ожидания завершения предыдущих задач. Вместо того, чтобы блокировать выполнение программы в ожидании, асинхронность позволяет переключаться между различными задачами, не прерывая выполнение основного потока.

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

Когда в программировании на Python применяется асинхронность

  • Сетевые операции. При выполнении операций ввода-вывода, таких как запросы к базам данных или сетевые запросы, асинхронность позволяет выполнять множество таких операций параллельно, минимизируя время ожидания.
  • Параллельные вычисления. Асинхронность позволяет выполнять различные вычисления одновременно, что особенно полезно при обработке больших объемов данных или выполнении сложных вычислений.
  • Пользовательский интерфейс. В программировании с графическим интерфейсом асинхронность позволяет выполнять длительные операции (например, загрузку данных из сети) без блокирования пользовательского интерфейса.

�� Python — Язык Возможностей: Python — это ключ к созданию приложений, работающих везде, от веб-сайтов до искусственного интеллекта.

�� Курс Python Start от Foxminded: Независимо от вашего опыта, этот курс поможет вам освоить основы Python!

�� Программа Курса:

  • Урок 1: Введение и настройка.
  • Урок 2: Работа с данными.
  • Урок 3: Функции и файлы.
  • Урок 4: ООП и классы.
  • Урок 5: Продвинутые инструменты.

�� Сертификация: Получите официальный сертификат по окончании курса.

Как асинхронность реализуется в Python

В Python асинхронность реализуется с использованием модуля `asyncio`, который предоставляет средства для создания асинхронных программ. Асинхронные функции помечаются ключевым словом `async`, а внутри таких функций используются корутины и событийный цикл для управления асинхронными операциями.

Пример асинхронной функции в Python:

```python import asyncio async def fetch_data(url): print("Начало загрузки данных") await asyncio.sleep(3) # Имитация задержки при загрузке print("Данные загружены") async def main(): tasks = [fetch_data("http://example.com") for _ in range(5)] await asyncio.gather(*tasks) if __name__ == "__main__": asyncio.run(main()) ```

В данном примере функция `fetch_data` является асинхронной и имитирует загрузку данных с задержкой. Функция `main` создает несколько задач (корутин) и выполняет их асинхронно с помощью событийного цикла.

Асинхронность в Python – это мощный инструмент для улучшения производительности программы при работе с сетевыми операциями, вычислениями и другими асинхронными задачами. Однако асинхронность может быть сложной для понимания и управления. Поэтому использовать ее надо в случаях, когда задачи действительно могут выполняться параллельно и есть явная выгода от ее использования.

Асинхронное программирование в Python: принципы и концепции

Асинхронное программирование в Python основано на идее эффективного управления несколькими задачами без блокировки выполнения основного потока. Это особенно полезно для операций ввода-вывода, таких как сетевые запросы и чтение-запись файлов, во время которых основной поток может переключаться на другие задачи.

Некоторые ключевые принципы и концепции асинхронного программирования в Python:

  1. Корутины (Coroutines) — это основной механизм асинхронного программирования в Python. Корутины представляют собой асинхронные функции, которые могут приостанавливать своё выполнение, позволяя другим корутинам запускаться в промежутках времени. Ключевое слово `async` используется для обозначения корутин.
```python async def my_coroutine(): # Асинхронные операции await asyncio.sleep(1) print("Корутина завершилась") ```
  1. Событийный цикл (Event Loop)- это основной механизм управления асинхронными задачами. Он работает как цикл, который постоянно проверяет состояние корутин и запускает их выполнение тогда, когда они готовы продолжить свою работу.
```python import asyncio async def main(): # Создаем событийный цикл loop = asyncio.get_event_loop() # Запускаем корутину в событийном цикле loop.create_task(my_coroutine()) # Запускаем событийный цикл loop.run_forever() # Вызываем функцию main asyncio.run(main()) ```
  1. Ключевое слово `await` используется в асинхронной функции для ожидания выполнения другой асинхронной операции. Функция `asyncio.sleep()` используется для имитации задержки в выполнении.
```python import asyncio async def my_coroutine(): print("Начало корутины") await asyncio.sleep(1) print("Корутина завершилась") asyncio.run(my_coroutine()) ```
  1. Асинхронные функции и объекты. В Python существует множество асинхронных функций и объектов в стандартной библиотеке и сторонних модулях, которые позволяют выполнять асинхронные операции, такие как сетевые запросы, базы данных, асинхронный ввод-вывод и другие.

Инструменты и библиотеки Python для асинхронного программирования

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

`asyncio`

`asyncio` — это стандартная библиотека Python, предназначенная для асинхронного программирования. Она включает в себя событийный цикл, который управляет асинхронными задачами и корутинами. `asyncio` предоставляет API для работы с сокетами, событиями, таймерами и другими асинхронными операциями.

`aiohttp`

`aiohttp` — это библиотека для выполнения асинхронных сетевых запросов. Она обеспечивает асинхронные клиенты HTTP и WebSocket, позволяя легко выполнять сетевые операции в асинхронном режиме.

`aiomysql`, `aiopg`

Это библиотеки для асинхронного взаимодействия с базами данных MySQL и PostgreSQL соответственно. Они позволяют выполнять запросы к базам данных асинхронно, что полезно при работе с большим количеством запросов.

Инструменты Python для асинхронного программирования

Похожие материалы

Моё мнение про Python

Основные аспекты изучения Python

Самые популярные библиотеки Python

Что должен знать Junior Python разработчик для устройства на работу

Среда разработки для Python: что это, какие они бывают и как их использовать

Что такое асинхронное программирование?

Это стиль программирования, при котором операции, которые могут занять много времени (например, ввод-вывод), выполняются параллельно основному потоку, не блокируя его.

Как в Python реализовать асинхронность?

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

В чем преимущества асинхронного программирования?

Асинхронность позволяет эффективно использовать ресурсы, особенно при операциях ввода-вывода, улучшая производительность и отзывчивость приложения.

Могу ли я использовать асинхронность с фреймворками вроде Django или Flask?

Flask поддерживает асинхронность начиная с версии 2.0. Django также начал внедрять асинхронные возможности, но полная асинхронность еще не реализована.

Что такое event loop в контексте асинхронного программирования?

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

Что такое coroutines в Python?

Coroutines — это специальные функции, которые могут приостанавливать свое выполнение и передавать управление обратно в event loop, ожидая выполнения другой операции.

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

Обложка поста Асинхронное программирование в Python

Асинхронное программирование на Python становится все более популярным. Для этих целей существует множество различных библиотек. Самая популярная из них – Asyncio, которая является стандартной библиотекой Python 3.4. Из этой статьи вы узнаете, что такое асинхронное программирование и чем отличаются различные библиотеки, реализующие асинхронность в Python.

По очереди

В каждой программе строки кода выполняются поочередно. Например, если у вас есть строка кода, которая запрашивает что-либо с сервера, то это означает, что ваша программа не делает ничего во время ожидания ответа. В некоторых случаях это допустимо, но во многих — нет. Одним из решений этой проблемы являются потоки (threads).

Потоки дают возможность вашей программе выполнять ряд задач одновременно. Конечно, у потоков есть ряд недостатков. Многопоточные программы являются более сложными и, как правило, более подвержены ошибкам. Они включают в себя такие проблемы: состояние гонки (race condition), взаимная (deadlock) и активная (livelock) блокировка, исчерпание ресурсов (resource starvation).

Переключение контекста

Хотя асинхронное программирование и позволяет обойти проблемные места потоков, оно было разработано для совершенно другой цели — для переключения контекста процессора. Когда у вас есть несколько потоков, каждое ядро процессора может запускать только один поток за раз. Для того, чтобы все потоки/процессы могли совместно использовать ресурсы, процессор очень часто переключает контекст. Чтобы упростить работу, процессор с произвольной периодичностью сохраняет всю контекстную информацию потока и переключается на другой поток.

Асинхронное программирование — это потоковая обработка программного обеспечения / пользовательского пространства, где приложение, а не процессор, управляет потоками и переключением контекста. В асинхронном программировании контекст переключается только в заданных точках переключения, а не с периодичностью, определенной CPU.

Эффективный секретарь

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

Потоки — это пять секретарей, у каждого из которых по одной задаче, но только одному из них разрешено работать в определенный момент времени. Для того, чтобы секретари работали в потоковом режиме, необходимо устройство, которое контролирует их работу, но ничего не понимает в самих задачах. Поскольку устройство не понимает характер задач, оно постоянно переключалось бы между пятью секретарями, даже если трое из них сидят, ничего не делая. Около 57% (чуть меньше, чем 3/5) переключения контекста были бы напрасны. Несмотря на то, что переключение контекста процессора является невероятно быстрым, оно все равно отнимает время и ресурсы процессора.

Зеленые потоки

Зеленые потоки (green threads) являются примитивным уровнем асинхронного программирования. Зеленый поток — это обычный поток, за исключением того, что переключения между потоками производятся в коде приложения, а не в процессоре. Gevent — известная Python-библиотека для использования зеленых потоков. Gevent — это зеленые потоки и сетевая библиотека неблокирующего ввода-вывода Eventlet. Gevent.monkey изменяет поведение стандартных библиотек Python таким образом, что они позволяют выполнять неблокирующие операции ввода-вывода. Вот пример использования Gevent для одновременного обращения к нескольким URL-адресам:

import gevent.monkey from urllib.request import urlopen gevent.monkey.patch_all() urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'] def print_head(url): print('Starting <>'.format(url)) data = urlopen(url).read() print('<>: <> bytes: <>'.format(url, len(data), data)) jobs = [gevent.spawn(print_head, _url) for _url in urls] gevent.wait(jobs) 

Как видите, API-интерфейс Gevent выглядит так же, как и потоки. Однако за кадром он использует сопрограммы (coroutines), а не потоки, и запускает их в цикле событий (event loop) для постановки в очередь. Это значит, что вы получаете преимущества потоков, без понимания сопрограмм, но вы не избавляетесь от проблем, связанных с потоками. Gevent — хорошая библиотека, но только для тех, кто понимает, как работают потоки.

Давайте рассмотрим некоторые аспекты асинхронного программирования. Один из таких аспектов — это цикл событий. Цикл событий — это очередь событий/заданий и цикл, который вытягивает задания из очереди и запускает их. Эти задания называются сопрограммами. Они представляют собой небольшой набор команд, содержащих, помимо прочего, инструкции о том, какие события при необходимости нужно возвращать в очередь.

Функция обратного вызова (callback)

В Python много библиотек для асинхронного программирования, наиболее популярными являются Tornado, Asyncio и Gevent. Давайте посмотрим, как работает Tornado. Он использует стиль обратного вызова (callbacks) для асинхронного сетевого ввода-вывода. Обратный вызов — это функция, которая означает: «Как только это будет сделано, выполните эту функцию». Другими словами, вы звоните в службу поддержки и оставляете свой номер, чтобы они, когда будут доступны, перезвонили, вместо того, чтобы ждать их ответа.
Давайте посмотрим, как сделать то же самое, что и выше, используя Tornado:

import tornado.ioloop from tornado.httpclient import AsyncHTTPClient urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'] def handle_response(response): if response.error: print("Error:", response.error) else: url = response.request.url data = response.body print('<>: <> bytes: <>'.format(url, len(data), data)) http_client = AsyncHTTPClient() for url in urls: http_client.fetch(url, handle_response) tornado.ioloop.IOLoop.instance().start() 

Предпоследняя строка кода вызывает метод AsyncHTTPClient.fetch , который получает данные по URL-адресу неблокирующим способом. Этот метод выполняется и возвращается немедленно. Поскольку каждая следующая строка будет выполнена до того, как будет получен ответ по URL-адресу, невозможно получить объект, как результат выполнения метода. Решение этой проблемы заключается в том, что метод fetch вместо того, чтобы возвращать объект, вызывает функцию с результатом или обратный вызов. Обратный вызов в этом примере — handle_response .

В примере вы можете заметить, что первая строка функции handle_response проверяет наличие ошибки. Это необходимо, потому что невозможно обработать исключение. Если исключение было создано, то оно не будет отрабатываться в коде из-за цикла событий. Когда fetch выполняется, он запускает HTTP-запрос, а затем обрабатывает ответ в цикле событий. К тому моменту, когда возникнет ошибка, стек вызовов будет содержать только цикл событий и текущую функцию, при этом нигде в коде не сработает исключение. Таким образом, любые исключения, созданные в функции обратного вызова, прерывают цикл событий и останавливают выполнение программы. Поэтому все ошибки должны быть переданы как объекты, а не обработаны в виде исключений. Это означает, что если вы не проверили наличие ошибок, то они не будут обрабатываться.
Другая проблема с обратными вызовами заключается в том, что в асинхронном программировании единственный способ избегать блокировок — это обратный вызов. Это может привести к очень длинной цепочке: обратный вызов после обратного вызова после обратного вызова. Поскольку теряется доступ к стеку и переменным, вы в конечном итоге переносите большие объекты во все ваши обратные вызовы, но если вы используете сторонние API-интерфейсы, то не можете передать что-либо в обратный вызов, если он этого не может принять. Это также становится проблемой, потому что каждый обратный вызов действует как поток. Например, вы хотели бы вызвать три API-интерфейса и дождаться, пока все три вернут результат, чтобы его обобщить. В Gevent вы можете это сделать, но не с обратными вызовами. Вам придется немного поколдовать, сохраняя результат в глобальной переменной и проверяя в обратном вызове, является ли результат окончательным.

Сравнения

Если вы хотите предотвратить блокировку ввода-вывода, вы должны использовать либо потоки, либо асинхронность. В Python вы выбираете между зелеными потоками и асинхронным обратным вызовом. Вот некоторые из их особенностей:

Зеленые потоки

  • потоки управляются на уровне приложений, а не аппаратно;
  • включают в себя все проблемы потокового программирования.

Обратный вызов

  • сопрограммы невидимы для программиста;
  • обратные вызовы ограничивают использование исключений;
  • обратные вызовы трудно отлаживаются.

Как решить эти проблемы?

Вплоть до Python 3.3 зеленые потоки и обратный вызов были оптимальными решениями. Чтобы превзойти эти решения, нужна поддержка на уровне языка. Python должен каким-то образом частично выполнить метод, прекратить выполнение, поддерживая при этом объекты стека и исключения. Если вы знакомы с концепциями Python, то понимаете, что я намекаю на генераторы. Генераторы позволяют функции возвращать список по одному элементу за раз, останавливая выполнение до того момента, когда следующий элемент будет запрошен. Проблема с генераторами заключается в том, что они полностью зависят от функции, вызывающей его. Другими словами, генератор не может вызвать генератор. По крайней мере так было до тех пор, пока в PEP 380 не добавили синтаксис yield from , который позволяет генератору получить результат другого генератора. Хоть асинхронность и не является главным назначением генераторов, они содержат весь функционал, чтобы быть достаточно полезными. Генераторы поддерживают стек и могут создавать исключения. Если бы вы написали цикл событий, в котором бы запускались генераторы, у вас получилась бы отличная асинхронная библиотека. Именно так и была создана библиотека Asyncio.

Все, что вам нужно сделать, это добавить декоратор @coroutine , а Asyncio добавит генератор в сопрограмму. Вот пример того, как обработать те же три URL-адреса, что и раньше:

import asyncio import aiohttp urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'] @asyncio.coroutine def call_url(url): print('Starting <>'.format(url)) response = yield from aiohttp.get(url) data = yield from response.text() print('<>: <> bytes: <>'.format(url, len(data), data)) return data futures = [call_url(url) for url in urls] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(futures)) 

Прим. перев. В примерах используется aiohttp версии 1.3.5. В последней версии библиотеки синтаксис другой.

Несколько особенностей, которые нужно отметить:

  • ошибки корректно передаются в стек;
  • можно вернуть объект, если необходимо;
  • можно запустить все сопрограммы;
  • нет обратных вызовов;
  • строка 10 не выполнится до тех пор, пока строка 9 не будет полностью выполнена.

Единственная проблема заключается в том, что объект выглядит как генератор, и это может вызвать проблемы, если на самом деле это был генератор.

Async и Await

Библиотека Asyncio довольно мощная, поэтому Python решил сделать ее стандартной библиотекой. В синтаксис также добавили ключевое слово async . Ключевые слова предназначены для более четкого обозначения асинхронного кода. Поэтому теперь методы не путаются с генераторами. Ключевое слово async идет до def , чтобы показать, что метод является асинхронным. Ключевое слово await показывает, что вы ожидаете завершения сопрограммы. Вот тот же пример, но с ключевыми словами async / await:

import asyncio import aiohttp urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'] async def call_url(url): print('Starting <>'.format(url)) response = await aiohttp.get(url) data = await response.text() print('<>: <> bytes: <>'.format(url, len(data), data)) return data futures = [call_url(url) for url in urls] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(futures)) 

Программа состоит из метода async . Во время выполнения он возвращает сопрограмму, которая затем находится в ожидании.

Заключение

В Python встроена отличная асинхронная библиотека. Давайте еще раз вспомним проблемы потоков и посмотрим, решены ли они теперь:

  • процессорное переключение контекста: Asyncio является асинхронным и использует цикл событий. Он позволяет переключать контекст программно;
  • состояние гонки: поскольку Asyncio запускает только одну сопрограмму и переключается только в точках, которые вы определяете, ваш код не подвержен проблеме гонки потоков;
  • взаимная/активная блокировка: поскольку теперь нет гонки потоков, то не нужно беспокоиться о блокировках. Хотя взаимная блокировка все еще может возникнуть в ситуации, когда две сопрограммы вызывают друг друга, это настолько маловероятно, что вам придется постараться, чтобы такое случилось;
  • исчерпание ресурсов: поскольку сопрограммы запускаются в одном потоке и не требуют дополнительной памяти, становится намного сложнее исчерпать ресурсы. Однако в Asyncio есть пул «исполнителей» (executors), который по сути является пулом потоков. Если запускать слишком много процессов в пуле исполнителей, вы все равно можете столкнуться с нехваткой ресурсов.

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

Существует несколько вариантов асинхронного программирования в Python. Вы можете использовать зеленые потоки, обратные вызовы или сопрограммы. Хотя вариантов много, лучший из них — Asyncio. Если используете Python 3.5, то вам лучше использовать эту библиотеку, так как она встроена в ядро ​​python.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *