Для каких типов задач в Python предназначен модуль asyncio

Ответ

Модуль asyncio в Python предназначен для эффективного решения I/O-bound (задачи, ограниченные вводом-выводом) проблем с помощью кооперативной многозадачности и цикла событий (event loop).

Он идеально подходит для сценариев, где программа тратит большую часть времени на ожидание внешних ресурсов, таких как:

  • Сетевые операции: HTTP-запросы, работа с веб-сокетами, взаимодействие с базами данных.
  • Работа с файловой системой: асинхронное чтение и запись файлов.
  • Обработка множества одновременных подключений: создание высокопроизводительных веб-серверов, чат-ботов, парсеров.

Ключевое преимущество: asyncio позволяет управлять тысячами одновременных операций в одном потоке, избегая накладных расходов на создание и переключение системных потоков.

Пример: асинхронные HTTP-запросы

import asyncio
import aiohttp

async def fetch_url(session, url):
    async with session.get(url) as response:
        print(f"Статус для {url}: {response.status}")
        return await response.text()

async def main():
    urls = [
        'http://python.org',
        'http://github.com',
        'https://fastapi.tiangolo.com/'
    ]
    async with aiohttp.ClientSession() as session:
        # Запускаем все задачи конкурентно и ждем их завершения
        tasks = [fetch_url(session, url) for url in urls]
        await asyncio.gather(*tasks)

# Запуск асинхронной программы
if __name__ == "__main__":
    asyncio.run(main())

Когда не стоит использовать asyncio? Для CPU-bound задач (вычисления, обработка данных), которые нагружают процессор, asyncio не даст прироста производительности. В таких случаях следует использовать модуль multiprocessing.

Ответ 18+ 🔞

Давай разберём эту тему про asyncio, а то некоторые думают, что это волшебная таблетка от всех болячек. Ну, типа, подсыпал в код — и всё летает. Хуй там, дружок.

Вот смотри, asyncio — это, по сути, твой личный диспетчер для ленивых работяг. Представь, что у тебя есть один чувак (один поток), но он умеет жонглировать хуёвой тучей задач. Не потому что он супермен, а потому что он не тупо ждёт, пока какая-то операция упрётся рогом в стену. Пока одна задача ждёт ответа от сервера (например, «эй, гитхаб, отдай мне свою главную страницу, сука»), он уже переключается на другую. Это и есть кооперативная многозадачность, или, как я это называю, «хитрая жопа».

Идеально это для всего, где программа в основном спит, простите, ожидает: сетевые запросы, чтение с диска (если библиотека асинхронная), общение с базами данных. То есть для I/O-bound задач, где процессор простаивает, как лох на остановке.

А вот если у тебя задачи CPU-bound — там, где нужно дрючить числа, кодировать видео или тренировать нейросеть — то asyncio тебе нихуя не поможет. Тут процессор и так пашет в полную силу, переключаться ему не на что. От такого диспетчера толку, как от козла молока. Тут уже нужен multiprocessing, чтобы разогнать работу по нескольким ядрам — вот это даст реальный прирост.

Смотри на примере, как это выглядит в коде. Я оставил его как есть, не трогаю святое.

import asyncio
import aiohttp

async def fetch_url(session, url):
    async with session.get(url) as response:
        print(f"Статус для {url}: {response.status}")
        return await response.text()

async def main():
    urls = [
        'http://python.org',
        'http://github.com',
        'https://fastapi.tiangolo.com/'
    ]
    async with aiohttp.ClientSession() as session:
        # Запускаем все задачи конкурентно и ждем их завершения
        tasks = [fetch_url(session, url) for url in urls]
        await asyncio.gather(*tasks)

# Запуск асинхронной программы
if __name__ == "__main__":
    asyncio.run(main())

Видишь? Мы создаём кучу задач — сходить на разные сайты. И вместо того чтобы ходить по очереди и каждый раз ждать, пока один сайт ответит, мы говорим: «А давайте-ка все вместе, пацаны!». asyncio.gather — это как крикнуть «По коням!». Все запросы стартуют почти одновременно, и наш цикл событий ловко перепрыгивает между ними, пока они ждут ответа от сети. В итоге три запроса выполнятся за время, примерно равное самому медленному из них, а не сумме всех трёх. Вот это и есть магия, блядь.

Так что запомни: asyncio — не для вычислений, а для ожидания. Для вычислений бери молоток потяжелее. Всё, лекция окончена, можешь идти применять.