← Назад к вопросам

Зачем нужны таски?

1.7 Middle🔥 141 комментариев
#Git и VCS#Асинхронность и многопоточность#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое таски в Python?

Таски (tasks) — это объекты из модуля asyncio, которые представляют асинхронные операции, обёрнутые в удобный интерфейс. Таск — это функция с await, которая выполняется конкурентно с другими тасками.

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

Таск vs Корутина

  • Корутина — функция с async def, возвращает объект корутины
  • Таск — обёртка над корутиной, которая реально выполняется в event loop
import asyncio

async def my_coroutine():
    return "результат"

# Корутина (не выполняется)
coro = my_coroutine()

# Таск (выполняется конкурентно)
task = asyncio.create_task(my_coroutine())

Создание тасков

# 1. asyncio.create_task() — создаёт таск для корутины
async def main():
    task = asyncio.create_task(my_coroutine())
    await task

# 2. asyncio.gather() — создаёт несколько тасков параллельно
async def main():
    results = await asyncio.gather(
        my_coroutine(),
        my_coroutine(),
        my_coroutine()
    )

# 3. asyncio.TaskGroup() — более строгая версия (Python 3.11+)
async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(my_coroutine())
        task2 = tg.create_task(my_coroutine())

Зачем нужны таски?

1. Конкурентное выполнение

import asyncio
import time

async def fetch_url(url, delay):
    await asyncio.sleep(delay)
    return f"Данные с {url}"

async def main():
    # Без тасков — выполнится последовательно (3 сек)
    # result1 = await fetch_url("url1", 1)
    # result2 = await fetch_url("url2", 1)
    # result3 = await fetch_url("url3", 1)
    
    # С тасками — выполнится параллельно (1 сек)
    results = await asyncio.gather(
        fetch_url("url1", 1),
        fetch_url("url2", 1),
        fetch_url("url3", 1),
    )
    return results

# Запуск
results = asyncio.run(main())

2. Отслеживание состояния

async def main():
    task = asyncio.create_task(my_coroutine())
    
    # Проверяем состояние
    print(task.done())  # False
    await asyncio.sleep(0.1)
    print(task.done())  # True
    
    # Получаем результат
    result = task.result()

3. Отмена тасков

async def main():
    task = asyncio.create_task(long_operation())
    
    await asyncio.sleep(1)
    task.cancel()  # Отменяем таск
    
    try:
        await task
    except asyncio.CancelledError:
        print("Таск отменён")

4. Timeout для тасков

async def main():
    try:
        result = await asyncio.wait_for(
            fetch_data(),
            timeout=5.0  # 5 секунд
        )
    except asyncio.TimeoutError:
        print("Таск превысил время выполнения")

Практический пример: Работник с очередью

import asyncio

queue = asyncio.Queue()

async def worker(name):
    while True:
        item = await queue.get()
        if item is None:  # Сигнал выхода
            break
        print(f"{name} обрабатывает {item}")
        await asyncio.sleep(1)
        queue.task_done()

async def main():
    # Создаём несколько рабочих
    workers = [asyncio.create_task(worker(f"Worker-{i}")) for i in range(3)]
    
    # Добавляем задачи
    for i in range(10):
        await queue.put(f"Task-{i}")
    
    # Ждём выполнения
    await queue.join()
    
    # Останавливаем рабочих
    for _ in workers:
        queue.put_nowait(None)
    
    await asyncio.gather(*workers)

asyncio.run(main())

Когда использовать таски?

  • I/O операции — сетевые запросы, чтение файлов
  • Параллелизм — несколько независимых операций
  • Периодические задачи — background jobs, мониторинг
  • WebSocket — долгоживущие соединения
  • Микросервисы — асинхронные RPC вызовы