Какие знаешь подходы конкурентного выполнения кода в Python, помимо асинхронности?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Подходы конкурентного выполнения в Python
В Python существует несколько эффективных способов организации конкурентного выполнения кода, каждый с собственными преимуществами и сценариями применения.
Многопоточность (Threading)
Классический подход, когда несколько потоков выполняются в контексте одного процесса. Due to Global Interpreter Lock (GIL), это работает эффективно только для I/O-bound операций:
import threading
import time
def worker(name, seconds):
print(f"Поток {name} начинается")
time.sleep(seconds)
print(f"Поток {name} завершён")
threads = []
for i in range(3):
t = threading.Thread(target=worker, args=(f"T{i}", 2))
threads.append(t)
t.start()
for t in threads:
t.join() # ждём завершения всех потоков
Плюсы: простая синтаксис, удобна для I/O операций, лёгкий обмен данными.
Минусы: GIL препятствует true параллелизму, сложная синхронизация, race conditions.
Многопроцессность (Multiprocessing)
Создаёт отдельные процессы Python, обеспечивая true параллелизм для CPU-bound операций:
import multiprocessing
def cpu_bound_task(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
if __name__ == "__main__":
with multiprocessing.Pool(processes=4) as pool:
results = pool.map(cpu_bound_task, [1000] * 4)
print(f"Результаты: {results}")
Плюсы: true параллелизм, идеально для CPU-bound задач.
Минусы: высокие overhead, медленный обмен данными, потребление памяти.
Асинхронное выполнение (asyncio)
Однопоточный event loop, идеален для I/O-heavy приложений:
import asyncio
async def fetch_data(url, delay):
print(f"Загрузка {url}")
await asyncio.sleep(delay)
return f"data from {url}"
async def main():
tasks = [
fetch_data("https://api.example.com/1", 2),
fetch_data("https://api.example.com/2", 1),
]
results = await asyncio.gather(*tasks)
return results
result = asyncio.run(main())
Плюсы: минимальный overhead, высокая производительность, scalable.
Минусы: требует async/await синтаксис, весь стек должен быть асинхронным.
Выбор подхода
- Threading/ThreadPoolExecutor: I/O операции
- Multiprocessing: CPU-bound работы
- Asyncio: Микросервисы, web-серверы, много одновременных I/O операций