Экспериментальная поддержка многопоточности в Python
Начиная с версии 3.13, CPython имеет экспериментальную поддержку сборки Python под названием бесплатная многопоточность, где глобальная блокировка интерпретатора (GIL) отключена. Выполнение в режиме бесплатной многопоточности позволяет полностью использовать доступную вычислительную мощность, запуская потоки параллельно на имеющихся процессорных ядрах. Хотя не все программы извлекут из этого автоматическую выгоду, программы, разработанные с учетом многопоточности, будут работать быстрее на многоядерном оборудовании.
Режим бесплатной многопоточности находится в стадии разработки, и работа по его улучшению продолжается: ожидайте некоторые ошибки и значительное снижение производительности в однопоточном режиме.
В этом документе описываются последствия бесплатной многопоточности для кода Python. См. Поддержка расширений API C для бесплатной многопоточности для получения информации о том, как писать расширения C, которые поддерживают сборку в режиме бесплатной многопоточности.
См. также
PEP 703 – Делаем глобальную блокировку интерпретатора необязательной в CPython для общего описания Python с бесплатной многопоточностью.
Установка
Начиная с Python 3.13, официальные установщики macOS и Windows необязательно поддерживают установку двоичных файлов Python с бесплатной многопоточностью. Установщики доступны по адресу https://www.python.org/downloads/.
Для получения информации об других платформах, см. Руководство по установке Python с бесплатной многопоточностью — поддерживаемое сообществом руководство по установке Python с бесплатной многопоточностью.
При компиляции CPython из исходного кода, следует использовать параметр конфигурации --disable-gil для компиляции интерпретатора Python с бесплатной многопоточностью.
Идентификация Python с бесплатной многопоточностью
Чтобы проверить, поддерживает ли текущий интерпретатор бесплатную многопоточность, python -VV и sys.version содержат «экспериментальную сборку с бесплатной многопоточностью». Новая функция sys._is_gil_enabled() может использоваться для проверки, действительно ли GIL отключена в текущем процессе.
Переменная конфигурации sysconfig.get_config_var("Py_GIL_DISABLED") может использоваться для определения, поддерживает ли сборка бесплатную многопоточность. Если переменная установлена в значение 1, сборка поддерживает бесплатную многопоточность. Это рекомендуемый механизм для принятия решений, связанных с конфигурацией сборки.
Глобальная блокировка интерпретатора в Python с бесплатной многопоточностью
Сборки CPython с бесплатной многопоточностью поддерживают необязательное включение GIL во время выполнения с помощью переменной среды PYTHON_GIL или командной строки -X gil.
GIL также может быть автоматически включен при импорте модуля расширения C-API, который не явно отмечен как поддерживающий бесплатную многопоточность. В этом случае будет выведено предупреждение.
Помимо документации по отдельным пакетам, следующие веб-сайты отслеживают состояние поддержки бесплатной многопоточности популярными пакетами:
Безопасность потоков
Сборка CPython с бесплатной многопоточностью стремится обеспечить аналогичное поведение безопасности потоков на уровне Python, как и в стандартной сборке с включенным GIL. Встроенные типы, такие как dict, list и set, используют внутренние блокировки для защиты от одновременных изменений таким образом, что поведение аналогично GIL. Однако Python исторически не гарантировал конкретного поведения для одновременных изменений этих встроенных типов, поэтому это следует рассматривать как описание текущей реализации, а не гарантию текущего или будущего поведения.
Примечание
Рекомендуется использовать threading.Lock или другие примитивы синхронизации вместо полагания на внутренние блокировки встроенных типов, когда это возможно.
Известные ограничения
В этом разделе описаны известные ограничения сборки CPython с бесплатной многопоточностью.
Бессмертные объекты
Сборка с бесплатной многопоточностью версии 3.13 делает некоторые объекты бессмертными. Бессмертные объекты не удаляются и имеют счетчик ссылок, который никогда не изменяется. Это делается для избежания конкуренции за счетчик ссылок, что препятствовало бы эффективному масштабированию в многопоточном режиме.
Объект будет сделан бессмертным, когда новый поток запускается впервые после запуска основного потока. Следующие объекты бессмертны:
- функции, объявленные на уровне модуля
- методы дескрипторов
- объекты кода
- объекты модулей и их словари
- классы (объекты типов)
Поскольку бессмертные объекты никогда не удаляются, приложения, создающие множество объектов этих типов, могут столкнуться с увеличением использования памяти. Ожидается, что эта проблема будет решена в версии 3.14.
Кроме того, числовые и строковые литералы в коде, а также строки, возвращаемые sys.intern(), также бессмертны. Это поведение ожидается и в сборке 3.14 с бесплатной многопоточностью.
Объекты фреймов
Доступ к объектам фреймов из других потоков небезопасен, и это может привести к сбою вашей программы. Это означает, что sys._current_frames() обычно небезопасно использовать в сборке с бесплатной многопоточностью. Функции, такие как inspect.currentframe() и sys._getframe(), обычно безопасны, если полученный объект фрейма не передается другому потоку.
Итераторы
Использование одного и того же объекта итератора в нескольких потоках, как правило, небезопасно, и потоки могут видеть дублирующиеся или отсутствующие элементы при итерации или аварии интерпретатора.
Производительность в однопоточном режиме
Сборка с бесплатной многопоточностью имеет дополнительные накладные расходы при выполнении кода Python по сравнению со стандартной сборкой с включенным GIL. В 3.13 эти накладные расходы составляют около 40% в наборе тестов pyperformance. Программы, которые большую часть времени тратят на расширения C или ввода-вывода, заметят меньшее влияние. Наибольшее влияние связано с тем, что специализированный адаптивный интерпретатор (PEP 659) отключен в сборке с бесплатной многопоточностью. Ожидается, что он будет снова включен безопасным для потоков способом в версии 3.14. Эти накладные расходы ожидается сократить в будущих выпусках Python. Цель — снижение накладных расходов до 10% или меньше в наборе тестов pyperformance по сравнению со стандартной сборкой с включенным GIL.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/howto/free-threading-python.html