Вопрос проверяет понимание реального параллелизма в Python и его ограничений.
Python-потоки могут выполняться параллельно во время I/O-операций или при выполнении нативного кода без GIL. В чистом Python-коде параллельного выполнения нет из-за GIL. Реальный параллелизм достигается либо за счёт I/O, либо за счёт внешних библиотек. Для CPU-задач используют процессы.
Важно различать конкурентность и параллелизм.
Python-потоки выполняются параллельно, если:
поток ожидает I/O
GIL временно освобождён
код выполняется вне интерпретатора Python
Параллельно работают:
сетевые запросы
операции с диском
вызовы C-библиотек
Пример идеи:
# несколько потоков ждут ответы от сети
# CPU в это время обслуживает другие потоки
Параллелизм невозможен:
в CPU-bound Python-коде
при активных вычислениях
без освобождения GIL
Потоки лишь чередуются, но не работают одновременно.
Для вычислений применяют:
multiprocessing
joblib
NumPy с освобождением GIL
Python-потоки дают параллелизм только при I/O или вне GIL. Для вычислений требуется многопроцессная модель.