Ответ
В Python эти концепции реализованы с учётом Global Interpreter Lock (GIL), что накладывает ключевые ограничения.
Многопоточность (threading)
- Что это: Запуск нескольких потоков выполнения в рамках одного процесса. Потоки разделяют общую память (глобальные переменные, структуры данных).
- В Python (из-за GIL): GIL позволяет выполняться только одному потоку Python в любой момент времени, даже на многоядерном CPU. Это делает чистые потоки Python неэффективными для CPU-задач (вычисления, обработка изображений).
- Для чего использовать: Для I/O-bound задач, где потоки большую часть времени ожидают (сеть, диск, ввод-вывод). Пока один поток ждёт, GIL может быть передан другому.
import threading import requests
def download_url(url): response = requests.get(url) print(f"Downloaded {len(response.content)} bytes from {url}")
urls = ["https://example.com/1", "https://example.com/2"] threads = [] for url in urls: thread = threading.Thread(target=download_url, args=(url,)) thread.start() threads.append(thread) for t in threads: t.join() # I/O-bound задача хорошо распараллеливается потоками
### Многопроцессорность (`multiprocessing`)
* **Что это:** Запуск нескольких **независимых процессов**, каждый со своим интерпретатором Python и памятью. Обмен данными требует специальных механизмов (очереди, каналы, shared memory).
* **В Python (обход GIL):** Каждый процесс имеет свой GIL и может выполняться на отдельном ядре CPU. Это делает многопроцессорность **эффективной для CPU-задач**.
* **Для чего использовать:** Для **CPU-bound задач** (математические расчёты, обработка данных).
```python
import multiprocessing
import math
def calculate_factorial(n):
print(f"Calculating {n}!")
return math.factorial(n)
if __name__ == '__main__':
numbers = [1000, 2000, 3000]
with multiprocessing.Pool(processes=3) as pool:
results = pool.map(calculate_factorial, numbers) # CPU-bound задача
print(results)
| Сводная таблица: | Критерий | Многопоточность (threading) |
Многопроцессорность (multiprocessing) |
|---|---|---|---|
| Единица выполнения | Поток (Thread) | Процесс (Process) | |
| Память | Общая | Раздельная (требует IPC) | |
| GIL в Python | Один на все потоки (ограничивает CPU) | Свой GIL на каждый процесс | |
| Идеально для | I/O-bound задачи (сеть, файлы) | CPU-bound задачи (вычисления) | |
| Накладные расходы | Низкие | Высокие (запуск процесса, IPC) |