Ответ
Субинтерпретаторы (Subinterpreters) в Python — это механизм, позволяющий запускать несколько изолированных экземпляров интерпретатора Python в рамках одного процесса.
Основная цель их введения — достижение истинного параллелизма для CPU-bound задач путем обхода ограничений глобальной блокировки интерпретатора (GIL), поскольку каждый субинтерпретатор имеет свой собственный GIL.
Ключевые особенности
- Изоляция GIL: Каждый субинтерпретатор имеет свою собственную блокировку GIL, что позволяет коду в разных субинтерпретаторах выполняться по-настоящему параллельно на многоядерных процессорах.
- Изоляция состояния: Объекты и глобальные переменные не разделяются между субинтерпретаторами, что предотвращает гонки данных, но усложняет взаимодействие.
- Обмен данными: Взаимодействие между ними возможно только через специальные каналы (channels), что обеспечивает безопасность.
Пример использования (экспериментальный API)
# Модуль является экспериментальным и может измениться
import _xxsubinterpreters as subinterpreters
import textwrap
# Создаем новый субинтерпретатор
interp_id = subinterpreters.create()
# Код для выполнения в новом интерпретаторе
code = textwrap.dedent("""
import threading
print(f"Hello from subinterpreter! Thread ID: {threading.get_ident()}")
""")
# Запускаем код в созданном субинтерпретаторе
subinterpreters.run_string(interp_id, code)
# Уничтожаем субинтерпретатор для освобождения ресурсов
subinterpreters.destroy(interp_id)
На данный момент (Python 3.12) API для работы с субинтерпретаторами все еще считается нестабильным и не предназначен для использования в production. Однако работа над ним активно ведется, и в будущем он может стать стандартным способом для параллельных вычислений в Python.
Ответ 18+ 🔞
Да ты послушай, что эти умники придумали! Субинтерпретаторы, блядь. Ну, представляешь, как будто в одной хате несколько квартир, и в каждой — свой, ёпта, отдельный пайтон живёт, со своим замком на двери (это GIL, если что). И главное — они друг другу не мешают! Один там интегралы ебёт, другой — JSON'ы парсит, и оба по-настоящему, на разных ядрах процессора, а не как обычно, по очереди, как последние лохи.
Чё за фишка, внатуре:
- Свой GIL, как личный горшок: У каждого субинтерпретатора — своя блокировка. Нет больше этой всенародной очереди в один сортир. Хуй с горы — работай параллельно, если железо позволяет.
- Полная изоляция, как в боксе: Объекты из одной "квартиры" в другую просто так не переедут. Гонки данных? Нет, не слышали. Но и просто так пообщаться не выйдет — придётся через спецканалы, как через трубку домофона.
- Общаться — только по каналам: Взаимодействие есть, но контролируемое, чтоб не началась драка за общий телевизор.
Смотри, как это выглядит (но это пока что чисто экспериментал, на коленке, блядь!):
# Модуль — тот ещё подопытный кролик, всё может поменяться
import _xxsubinterpreters as subinterpreters
import textwrap
# Создаём новую изолированную хату-интерпретатор
interp_id = subinterpreters.create()
# Код, который будет там внутри вариться
code = textwrap.dedent("""
import threading
print(f"Hello from subinterpreter! Thread ID: {threading.get_ident()}")
""")
# Запуляем этот код в новосозданной квартире
subinterpreters.run_string(interp_id, code)
# После вечеринки — убираем за собой, уничтожаем интерпретатор
subinterpreters.destroy(interp_id)
Вот такая, блядь, картина. Пока что это как игрушка для гиков в Python 3.12 — трогать в продакшене страшно, всё может накрыться медным тазом. Но идея-то, сука, огонь! Если её доведут до ума, это ж будет настоящий прорыв, чтобы наконец-то заставить CPU-bound задачи в Питоне пахать, как проклятые, а не переминаться с ноги на ногу.