Вопрос проверяет понимание того, в каких ситуациях Python-потоки могут реально переключаться и не блокировать друг друга.
GIL освобождается во время блокирующих I/O-операций, таких как чтение из сети, работа с файлами или ожидание таймера. В этих случаях поток приостанавливается, и другой поток может продолжить выполнение. Также GIL может освобождаться в нативном коде, если он явно это делает. Чистые вычисления в Python GIL не освобождают.
Поведение GIL напрямую связано с тем, выполняется ли байткод Python или ожидание внешнего ресурса.
GIL освобождается, когда поток:
ждёт завершения I/O-операции
вызывает системный вызов, который может блокироваться
заходит в нативный код, явно освобождающий GIL
Типичные примеры:
чтение из сокета
запрос к БД
time.sleep()
Во время ожидания I/O:
поток не использует CPU
удержание GIL не имеет смысла
другие потоки могут быть полезны
Это позволяет эффективно использовать потоки для I/O-bound задач.
Некоторые библиотеки:
освобождают GIL вручную
выполняют тяжёлые вычисления параллельно
Пример (концептуально):
# C-расширение выполняет код без GIL
# Python-потоки в это время могут работать
GIL освобождается при ожидании I/O и в нативном коде. Это делает Python-потоки полезными для I/O-задач, но не для чистых вычислений.