Python — не только про скрипты и автоматизацию. Он умеет работать сразу с несколькими задачами параллельно — и делать это красиво. Но тут есть нюансы: GIL, multiprocessing, asyncio... разберём всё!
👨💻 Процессы vs Потоки vs Асинхронность
* Процессы (multiprocessing) — как отдельные контейнеры. Изолированы, не делят память. Каждый процесс может использовать своё ядро процессора. Идеально для вычислений.
* Потоки (threading) — живут в одном процессе и делят между собой память. Отлично справляются с задачами, связанными с вводом/выводом (например, скачивание файлов).
* Асинхронность (asyncio) — не параллельность в классическом смысле. Всё работает в одном потоке, но задачи переключаются между собой, не блокируя выполнение. Лучший выбор для работы с сетью.
💬 А что там с GIL?
GIL — глобальная блокировка интерпретатора в Python. Она позволяет одновременно выполняться только одному потоку Python-кода, даже если у тебя 64 ядра. Почему так? Потому что управление памятью в CPython не потокобезопасно.
⚠️ Важно: GIL не мешает использовать multiprocessing, потому что каждый процесс имеет свой интерпретатор.
⚙️ Какой инструмент для чего?
💥
multiprocessing> Идеален для тяжёлых вычислений на нескольких ядрах.
*
Process — запуск нового процесса*
Pool — пул воркеров*
Queue, Pipe — обмен данными*
Manager — разделение объектов между процессами*
Lock, Semaphore — синхронизация*
cpu_count() — сколько у тебя вообще ядер?⚡️
threading> Для I/O задач, где важна отзывчивость: загрузка веб-страниц, параллельный логинг и т.д.
*
Thread — запуск нового потока*
Timer, Event, Barrier — управление временем и синхронизацией*
enumerate(), current_thread() — управление потоками🌐
asyncio> Современный подход: запуск кучи задач внутри одного потока.
*
async / await — ключевые слова*
asyncio.run(), asyncio.gather() — запуск корутин* Поддержка библиотек:
*
aiohttp — запросы к сайтам*
aiofiles — работа с файлами🔒 Условия гонки и безопасность
Race condition (состояние гонки) — когда два потока одновременно хотят изменить одну и ту же переменную. Кто первый встал — того и тапки. Итог: баги, которых потом не найдёшь.
Потокобезопасность достигается через:
*
Lock, RLock* Локальные данные потока (
threading.local())✅ Асинхронность в деталях
Асинхронная программа:
* запускает задачу;
* пока ждёт ответа — делает что-то ещё;
* возвращается к задаче, когда пришёл ответ.
Пример:
import asyncio
import aiohttp
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
return await resp.text()
async def main():
html = await fetch('https://example.com')
print(html)
asyncio.run(main())
📌 Главное по теме:
🔧 Сравнение подходов:
📌 multiprocessing
• Параллельность: ✅
• Делит память: ❌
• Для чего: тяжёлые CPU-задачи
📌 threading
• Параллельность: ❌ (из-за GIL)
• Делит память: ✅
• Для чего: задачи с вводом/выводом (I/O)
📌 asyncio
• Параллельность: ❌
• Делит память: ✅
• Для чего: сетевые и файловые задачи
🔥 Закрепим:
* Нужна мощь ядра? —
multiprocessing* Много сетевых вызовов и ожиданий? —
asyncio* Быстрая и простая многозадачность? —
threading* GIL — особенность Python, но не приговор
📂 Сохраняй шпаргалку, пригодится!
@python2day
#doc #python #cheatsheet
