В Python стандартная библиотека предоставляет модуль threading для многопоточности. Потоки позволяют выполнять несколько операций параллельно в рамках одного процесса. Однако в стандартной реализации Python (CPython) существует механизм GIL (Global Interpreter Lock) — глобальная блокировка интерпретатора, которая разрешает только одному потоку выполнять байткод Python одновременно.
Это означает, что в CPython многопоточность не позволяет достигать реального параллелизма при выполнении Python-кода на уровне процессора; параллельность полезна только для задач, связанных с ожиданием (I/O-bound). Для CPU-bound задач рекомендуется использовать модуль multiprocessing, который запускает несколько процессов и обходит GIL.
Пример:
import threading def worker(): print('Start') # тяжелые вычисления print('End') threads = [threading.Thread(target=worker) for _ in range(5)] for t in threads: t.start() for t in threads: t.join()
Для параллелизма при интенсивных вычислениях применяйте multiprocessing:
from multiprocessing import Pool def square(x): return x*x with Pool(4) as p: print(p.map(square, [1, 2, 3, 4]))
Может ли многопоточность в Python ускорить выполнение compute-heavy задач?
Ответ: Нет, из-за GIL в стандартной реализации Python (CPython) потоки не дадут прироста производительности на CPU-bound задачах; для таких задач используйте multiprocessing или сторонние реализации интерпретатора (например, Jython, IronPython), не имеющие GIL.
История
В проекте по обработке больших объёмов данных команда попыталась ускорить вычисления с помощью потоков (
threading). Вместо ускорения время работы увеличилось, потому что GIL не давал потокам работать параллельно; после перехода наmultiprocessingзадача была решена.
История
Разработчик пытался одновременно скачивать большие файлы и обрабатывать их в нескольких потоках, но часто натыкался на "deadlock" из-за неосторожного использования общих переменных без блокировок (thread safety).
История
На backend-сервере были реализованы обработка тяжёлых запросов в thread-пуле. При росте нагрузки сервер начал "замирать" — выяснилось, что большинство времени потоки проводили в ожидании выполнения Python-кода из-за GIL, хотя запросы не были связаны с интенсивным I/O.