Короткий ответ
GIL (Global Interpreter Lock) — блокировка в эталонной реализации CPython, которая позволяет только одному потоку исполнять байткод Python в любой момент времени. Она появилась из-за непотокобезопасного подсчёта ссылок, ограничивает вычислительные задачи, а вот задачи ввода-вывода от потоков по-прежнему выигрывают.
Как это работает подробнее
Многопоточность в Python существует, но из-за GIL реально параллельно по байткоду исполняется только один поток.
- Суть механизма. GIL — мьютекс, удерживаемый единственным потоком: даже в многоядерной системе два потока одного процесса не выполняют Python-байткод одновременно.
- Причина появления. Управление памятью в CPython, в частности подсчёт ссылок, не потокобезопасно; GIL упрощает его и избавляет разработчиков от множества ошибок с общими объектами.
- Что страдает. CPU-bound программы не ускоряются от добавления потоков, тогда как I/O-bound задачи дают выигрыш благодаря ожиданиям ввода-вывода.
- Обходные пути. Настоящий параллелизм дают отдельные процессы через
multiprocessingи внешние C-библиотеки вроде NumPy, которые освобождают GIL при вычислениях.
Пример кода
Синхронизация потоков блокировкой
# GIL не позволяет двум потокам исполнять Python-байткод одновременно
import threading
counter = 0
lock = threading.Lock()
def worker():
global counter
for _ in range(100000):
with lock: # синхронизация общего состояния
counter += 1
threads = [threading.Thread(target=worker) for _ in range(2)]
for t in threads: t.start()
for t in threads: t.join()
print(counter)Что использовать на практике
- I/O-bound задачи. Для ожидания сети, диска и API используй потоки — они дают выигрыш.
- CPU-bound задачи. Для вычислений на всех ядрах бери
multiprocessing. - Тяжёлая математика. Перекладывай вычисления на библиотеки вроде NumPy, которые освобождают GIL.
Подводные камни
- Ожидание ускорения. Потоки не ускоряют чистые Python-вычисления — об этом нельзя забывать при проектировании.
- Гонки данных. Даже с GIL общее состояние нужно защищать блокировками: переключение потоков происходит в любой момент.
- Особенность CPython. GIL есть в эталонной реализации CPython, а не в самом языке Python.
Как отвечать на собеседовании
- Дай определение GIL как блокировки на один поток в CPython → объясни причину появления, связанную с подсчётом ссылок → раздели CPU-bound и I/O-bound задачи → упомяни multiprocessing и C-библиотеки как способы обойти ограничение.