Этот вопрос проверяет понимание разных моделей параллельного выполнения в Python и умение выбирать подходящий инструмент под задачу.
Потоки позволяют выполнять несколько задач параллельно в рамках одного процесса, но в Python они ограничены GIL. Асинхронное выполнение использует один поток и переключается между задачами в моменты ожидания. Асинхронность особенно эффективна для операций ввода-вывода, например сетевых запросов. Потоки проще для понимания, но сложнее для контроля доступа к данным. Асинхронный код требует другого стиля написания, но часто работает эффективнее.
Асинхронность и потоки решают похожую задачу — выполнение нескольких операций «одновременно», но делают это принципиально разными способами.
Определение:
Поток — это отдельная линия выполнения внутри одного процесса, которая может работать параллельно с другими потоками.
Основные особенности:
Все потоки работают в одном адресном пространстве
В CPython существует GIL (Global Interpreter Lock)
Только один поток может выполнять Python-код в один момент времени
Типичные сценарии:
Работа с вводом-выводом (HTTP, файлы, сокеты)
Задачи, где важно простое распараллеливание
Пример:
import threading
def task():
print("Задача выполняется")
t = threading.Thread(target=task)
t.start()
t.join()
Определение:
Асинхронность — это модель конкурентности, где задачи добровольно уступают управление в точках ожидания (await).
Ключевые моменты:
Обычно используется один поток
Переключение задач происходит явно
Нет гонок потоков при работе с памятью
Пример:
import asyncio
async def task():
await asyncio.sleep(1)
print("Задача выполнена")
asyncio.run(task())
Потоки работают параллельно, асинхронность — конкурентно
Потоки требуют блокировок, асинхронность — нет
Асинхронность эффективнее для большого числа I/O операций
Вывод:
Используй асинхронность для сетевых и I/O задач с большим количеством ожиданий. Потоки подойдут, если нужен простой подход без переписывания кода под async/await.