Евгений Згурский
Евгений Згурский Создатель этого блога, студент группы ИДМ-24-08 в МГТУ «Станкин»

Асинхронное и конкурентное программирование в Python с использованием asyncio

Асинхронное и конкурентное программирование в Python с использованием asyncio

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

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

Основные концепции asyncio

Асинхронные функции

Асинхронные функции (или корутины) определяются с помощью ключевого слова async def. Они могут приостанавливать свое выполнение с помощью ключевого слова await, что позволяет другим корутинам выполняться в это время.

1
2
3
4
5
6
7
8
9
import asyncio

async def say_hello():
    print("Привет!")
    await asyncio.sleep(1)
    print("Пока!")

# Запуск корутины
asyncio.run(say_hello())

Цикл событий

Цикл событий (event loop) управляет выполнением асинхронных задач. Он запускает корутины и обрабатывает события, такие как завершение задач или поступление данных.

1
2
3
4
5
6
7
8
9
10
11
import asyncio

async def main():
    print("Начало")
    await asyncio.sleep(1)
    print("Конец")

# Получение текущего цикла событий
loop = asyncio.get_event_loop()
# Запуск корутины
loop.run_until_complete(main())

Задачи

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

1
2
3
4
5
6
7
8
9
10
11
12
import asyncio

async def say_hello():
    print("Привет!")
    await asyncio.sleep(1)
    print("Пока!")

async def main():
    task = asyncio.create_task(say_hello())
    await task

asyncio.run(main())

Примеры использования asyncio

Асинхронные запросы

Асинхронные запросы позволяют выполнять несколько HTTP-запросов одновременно, что может значительно ускорить работу с сетевыми ресурсами.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = ["https://example.com", "https://example.org", "https://example.net"]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)
    for result in results:
        print(result)

asyncio.run(main())

Асинхронная работа с файлами

Асинхронная работа с файлами позволяет выполнять операции чтения и записи без блокировки основного потока выполнения.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio
import aiofiles

async def write_file(filename, content):
    async with aiofiles.open(filename, 'w') as f:
        await f.write(content)

async def read_file(filename):
    async with aiofiles.open(filename, 'r') as f:
        return await f.read()

async def main():
    await write_file('example.txt', 'Привет, мир!')
    content = await read_file('example.txt')
    print(content)

asyncio.run(main())

Лучшие практики

Использование asyncio.run

Для запуска асинхронных функций рекомендуется использовать asyncio.run, так как он автоматически создает и закрывает цикл событий.

1
2
3
4
async def main():
    print("Привет, мир!")

asyncio.run(main())

Обработка исключений

При работе с асинхронными задачами важно обрабатывать исключения, чтобы избежать неожиданных ошибок.

1
2
3
4
5
6
7
8
9
10
11
12
13
import asyncio

async def faulty_task():
    raise ValueError("Что-то пошло не так!")

async def main():
    task = asyncio.create_task(faulty_task())
    try:
        await task
    except ValueError as e:
        print(f"Ошибка: {e}")

asyncio.run(main())

Ограничение количества одновременных задач

Для предотвращения перегрузки системы рекомендуется ограничивать количество одновременных задач с помощью семафоров.

1
2
3
4
5
6
7
8
9
10
11
12
13
import asyncio

async def limited_task(sem):
    async with sem:
        print("Выполнение задачи")
        await asyncio.sleep(1)

async def main():
    sem = asyncio.Semaphore(2)
    tasks = [limited_task(sem) for _ in range(5)]
    await asyncio.gather(*tasks)

asyncio.run(main())

Заключение

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

comments powered by Disqus