Содержание страницы
Экспериментальная поддержка свободной многопоточности в Python¶Python experimental support for free threading
Начиная с версии 3.13, в CPython появилась экспериментальная поддержка сборки Python, называемой свободной многопоточностью, в которой отключён глобальная блокировка интерпретатора (GIL). Выполнение в режиме свободной многопоточности позволяет полностью использовать доступную вычислительную мощность, запуская потоки параллельно на доступных ядрах CPU. Хотя не всё программное обеспечение выиграет от этого автоматически, программы, спроектированные с учётом многопоточности, будут работать быстрее на многоядерном оборудовании.
Режим свободной многопоточности является экспериментальным, и работа по его улучшению продолжается: ожидайте некоторые ошибки и существенное снижение производительности в однопоточном режиме.
В этом документе описываются последствия свободной многопоточности для Python-кода. Информацию о том, как писать расширения на C, поддерживающие сборку со свободной многопоточностью, см. в C API Extension Support for Free Threading.
См. также
PEP 703 – «Сделать глобальную блокировку интерпретатора опциональной в CPython» для общего описания Python со свободной многопоточностью.
Установка¶Installation
Начиная с Python 3.13, официальные установщики для macOS и Windows опционально поддерживают установку двоичных файлов Python со свободной многопоточностью. Установщики доступны по адресу https://www.python.org/downloads/.
Информацию о других платформах см. в Installing a Free-Threaded Python, руководстве по установке, поддерживаемом сообществом, для установки Python со свободной многопоточностью.
При сборке CPython из исходного кода для создания свободно-поточной сборки интерпретатора Python следует использовать опцию конфигурации --disable-gil.
Определение сборки со свободной потоковой обработкой¶Identifying free-threaded Python
Чтобы проверить, поддерживает ли текущий интерпретатор работу без GIL, python -VV
и sys.version содержат «experimental free-threading build».
Новая функция sys._is_gil_enabled() позволяет проверить,
действительно ли GIL отключен в текущем процессе.
Переменная конфигурации sysconfig.get_config_var("Py_GIL_DISABLED") позволяет определить, поддерживает ли сборка свободную потоковую обработку. Если переменная имеет значение 1, то сборка поддерживает свободную потоковую обработку. Это рекомендуемый механизм для принятия решений, связанных с конфигурацией сборки.
Глобальная блокировка интерпретатора в сборке со свободной потоковой обработкой¶The global interpreter lock in free-threaded Python
Сборки CPython со свободной потоковой обработкой поддерживают опциональную работу с включённой GIL во время выполнения с помощью переменной окружения PYTHON_GIL или опции командной строки -X gil.
GIL также может автоматически включаться при импорте модуля расширения C-API, который явно не помечен как поддерживающий свободную потоковую обработку. В этом случае будет выведено предупреждение.
В дополнение к документации отдельных пакетов, следующие сайты отслеживают статус поддержки свободной потоковой обработки популярными пакетами:
Потокобезопасность¶Thread safety
Сборка CPython со свободной потоковой обработкой стремится обеспечить на уровне Python поведение, аналогичное потокобезопасности сборки со включённой GIL по умолчанию. Встроенные типы, такие как dict, list и set, используют внутренние блокировки для защиты от одновременных изменений подобно GIL. Однако исторически Python не гарантировал конкретного поведения при одновременных изменениях этих встроенных типов, поэтому это следует рассматривать как описание текущей реализации, а не как гарантию текущего или будущего поведения.
Примечание
По возможности рекомендуется использовать threading.Lock или другие примитивы синхронизации вместо того, чтобы полагаться на внутренние блокировки встроенных типов.
Известные ограничения¶Known limitations
В этом разделе описаны известные ограничения сборки CPython со свободной потоковой обработкой.
Иммортализация¶Immortalization
Сборка со свободной многопоточностью в версии 3.13 делает некоторые объекты бессмертными. Бессмертные объекты не освобождаются и имеют счётчики ссылок, которые никогда не изменяются. Это сделано для предотвращения конкуренции за счётчик ссылок, которая могла бы помешать эффективному масштабированию многопоточности.
Объект становится бессмертным при первом запуске нового потока после того, как главный поток уже работает. Следующие объекты становятся бессмертными:
function объекты, объявленные на уровне модуля
method дескрипторы
code объекты
module объекты и их словари
classes (объекты типа)
Поскольку бессмертные объекты никогда не освобождаются, приложения, создающие много объектов этих типов, могут заметить увеличение использования памяти. Ожидается, что это будет исправлено в версии 3.14.
Кроме того, числовые и строковые литералы в коде, а также строки, возвращаемые sys.intern(), также становятся бессмертными. Ожидается, что это поведение сохранится в сборке со свободной многопоточностью 3.14.
Объекты фреймов¶Frame objects
Небезопасно обращаться к объектам frame из других потоков, и это может привести к аварийному завершению программы. Это означает, что sys._current_frames() в целом небезопасно использовать в сборке со свободной многопоточностью. Функции вроде inspect.currentframe() и sys._getframe() в целом безопасны, если результирующий объект frame не передаётся другому потоку.
Итераторы¶Iterators
Совместное использование одного и того же объекта итератора между несколькими потоками в целом небезопасно: потоки могут видеть дублирующиеся или пропущенные элементы при итерации или привести к аварийному завершению интерпретатора.
Производительность в однопоточном режиме¶Single-threaded performance
Сборка со свободной многопоточностью имеет дополнительные накладные расходы при выполнении кода Python по сравнению со стандартной сборкой с включённым GIL. В версии 3.13 эти накладные расходы составляют около 40% по набору тестов pyperformance. Программы, которые большую часть времени проводят в расширениях C или операциях ввода-вывода, увидят меньшее влияние. Наибольшее влияние связано с тем, что специализирующий адаптивный интерпретатор (PEP 659) отключён в сборке со свободной многопоточностью. Мы ожидаем, что включим его снова потокобезопасным способом в версии 3.14. Ожидается, что эти накладные расходы будут уменьшены в будущих версиях Python. Мы стремимся к накладным расходам 10% или менее по набору pyperformance по сравнению со стандартной сборкой с GIL.