concurrent.interpreters: публичный API для запуска нескольких полноценных интерпретаторов внутри одного процесса.Это финал длинной истории. PEP 554 в 2017 году описал идею, PEP 684 в 2023 дал каждому интерпретатору собственный GIL, и PEP 734, принятый в июне 2025, превратил всё это в стандартный Python-модуль. До 3.14 функционал был доступен только через C API.
API ровно такой, какой ожидаешь:
import concurrent.interpreters as interpreters
interp = interpreters.create()
interp.exec('print("Hello from subinterp")')
interp.close()
Каждый интерпретатор изолирован: своя память, свой GIL, свой импорт-кеш. Простые типы передаются через специальный канал без копирования, сложные идут через сериализацию вроде
pickle.Что это даёт:
— Настоящая многозадачность в одном процессе без
multiprocessing. Каждый интерпретатор едет на своём GIL и параллельно работает на отдельном ядре.— Совместимость с
asyncio. CPU-bound подзадачи можно гонять в субинтерпретаторах, а сетевой ввод-вывод оставить в основном цикле событий.— Один процесс. Общие файловые дескрипторы, единое управление, без накладных расходов на
fork и spawn.У подхода одно главное ограничение: C-расширения. Стабильность под per-interpreter GIL не гарантирована, и многим библиотекам ещё предстоит дозревать. Чистый Python и библиотеки с поддержкой PEP 684 работают, остальные могут падать.
PEP 734 и free-threading решают одну задачу разными способами. Free-threading убирает GIL вообще: больше совместимости, меньше изоляции. Sub-interpreters сохраняют GIL на интерпретатор: меньше совместимости, больше изоляции. Похоже, в долгую Python поддержит оба пути.
Свежий разбор с примерами и архитектурой: https://alexeev-dev.bearblog.dev/running-multiple-interpreters-in-python-code-incredible-speed/
@zen_of_python (теперь в VK и Max)
@zen_of_python (теперь в VK и Max)