Как ответить
GIL (Global Interpreter Lock) — это мьютекс, который есть в CPython, основной реализации Python. Он разрешает выполнять только один поток байткода в любой момент времени, даже на многоядерном процессоре. Нужен GIL для защиты внутренних структур интерпретатора и упрощения управления памятью, особенно сборки мусора и подсчёта ссылок.
С многопоточностью связь прямая: для CPU-интенсивных задач (численные расчёты, обработка изображений) GIL убивает выигрыш от потоков — программа будет работать не быстрее, а часто медленнее из-за накладных расходов на переключение. Для I/O-bound задач (сетевые запросы, чтение файлов) потоки работают нормально, потому что GIL отпускается на время блокирующей операции — например, time.sleep() или ожидание ответа от сокета освобождают GIL, и другие потоки могут исполняться.
Пример на синтетике: вычисление чисел Фибоначчи в четырёх потоках на четырёх ядрах не ускорится.
import threading, time
def cpu_bound():
x = 0
for _ in range(10**7):
x += 1
threads = [threading.Thread(target=cpu_bound) for _ in range(4)]
start = time.time()
for t in threads: t.start()
for t in threads: t.join()
print(time.time() - start) # ~1.2 сек (на одном ядре тоже ~1.2)Обойти GIL можно несколькими способами: использовать multiprocessing (каждый процесс со своим GIL, но дороже память), asyncio (конкурентность на одном потоке без переключений через GIL), или вынести тяжёлые вычисления в C-расширения (например, NumPy, который освобождает GIL на время работы).
Важный нюанс: GIL есть только в CPython. Альтернативные реализации (Jython, IronPython) его не имеют. В последних версиях Python (3.12+) разработчики пытаются сделать GIL опциональным через флаг -X gil=0, но он пока экспериментальный.