Что такое GIL?
- Зачем в Python глобальная блокировка интерпретатора?
- Почему потоки в Python не ускоряют вычисления?
- Можно ли обойти GIL?
GIL — блокировка в CPython: байткод Python в один момент выполняет только один поток.
- CPU-задачи потоки не ускоряют, задачи ввода-вывода — ускоряют: GIL отпускается на ожидании
- Для вычислений — процессы (
multiprocessing) или C-расширения, отпускающие GIL (NumPy)
А ещё С Python 3.13 есть отдельная сборка без GIL (PEP 703), по умолчанию GIL остаётся
Подробно
GIL (Global Interpreter Lock) — мьютекс внутри CPython. Поток должен держать его, чтобы выполнять байткод. Он упрощает управление памятью: подсчёт ссылок на объекты не нужно защищать отдельными блокировками, а C-расширения проще писать.
Что из этого следует:
- вычисления (CPU-bound) в нескольких потоках идут не быстрее, чем в одном: потоки по очереди получают GIL;
- ввод-вывод (сеть, диск, ожидание базы) — потоки помогают: на время ожидания поток отпускает GIL, и работают другие;
- многие C-библиотеки (NumPy, обработка изображений, сжатие) отпускают GIL на время своих вычислений и параллелятся в потоках.
Как обойти для вычислений: multiprocessing или concurrent.futures.ProcessPoolExecutor — у каждого процесса свой интерпретатор и свой GIL; вынести тяжёлое в C, Cython или Rust.
GIL не делает код потокобезопасным: операции вида x += 1 состоят из нескольких шагов байткода, и поток может прерваться посередине. Общие данные всё равно защищают Lock.
GIL — особенность CPython. Начиная с Python 3.13 есть экспериментальная сборка без GIL (free-threaded, PEP 703), но стандартная сборка работает с GIL.
Пример
import threading
from concurrent.futures import ProcessPoolExecutor
def cpu_task(n):
return sum(i * i for i in range(n))
# Потоки: CPU-задача не ускорится
threads = [threading.Thread(target=cpu_task, args=(10_000_000,)) for _ in range(4)]
# Процессы: настоящий параллелизм на нескольких ядрах
with ProcessPoolExecutor() as pool:
results = list(pool.map(cpu_task, [10_000_000] * 4))Что хотят услышать
- Что такое GIL и в какой реализации он есть.
- Разница влияния на CPU-bound и I/O-bound задачи.
- Способы обойти: процессы, C-расширения.
- GIL не заменяет блокировки для общих данных.
Частые ошибки
- «В Python потоки вообще бесполезны» — для ввода-вывода они работают.
- «GIL делает код потокобезопасным».
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗GIL не позволяет запускать больше одного потока, поэтому threading в CPython бесполезен даже для сети
- ✗Потоки ускоряют CPU-задачи благодаря GIL: он распределяет байткод между ядрами
- ✗GIL есть во всех реализациях Python, включая Jython и IronPython, — это часть языка
- ✓Блокировка в CPython: байткод в один момент выполняет только один поток
Что спросят дальше
Разбор темы
- Потоки, процессы и GIL
Что такое GIL и что он не защищает, когда выбирать потоки, процессы или asyncio, concurrent.futures, ограничения multiprocessing, сборка без GIL.
Связанные вопросы
- Как работают async и await? Junior
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.