Ответ 1
GIL в CPython 1 касается только исполняемого кода Python. Потокобезопасное расширение C, использующее много CPU, может выпустить GIL, если ему не нужно взаимодействовать со временем выполнения Python.
Как только код C должен "поговорить" с Python (прочитайте: вернитесь во время выполнения Python), тогда ему нужно снова получить GIL, то есть GIL должен установить защиту/атомное поведение для "интерпретатор" (и я использую этот термин свободно) и не должен одновременно запускать собственный/не-Python-код.
Освобождение GIL вокруг ввода-вывода (блокирование или нет, использование CPU или нет) - это одно и то же - пока данные не будут перемещены в Python, нет причин для получения GIL.
1 GIL является спорным, поскольку он предотвращает использование многопоточных программ CPython в полной мере в многопроцессорных системах в определенных ситуациях. Обратите внимание, что потенциально блокирующие или длительные операции, такие как обработка ввода-вывода, обработка изображений и хруст числа NumPy, происходят за пределами GIL. Поэтому только в многопоточных программах тратят много времени внутри GIL, интерпретируя байт-код CPython, что GIL становится узким местом.