Инициализация, завершение работы и потоки
Сведения о настройке интерпретатора перед инициализацией см. в разделе Конфигурация инициализации Python.
Перед инициализацией Python
В приложении, встраивающем Python, функцию Py_Initialize() необходимо вызвать до использования любых других функций API Python/C, за исключением нескольких функций и глобальных переменных конфигурации.
До инициализации Python можно безопасно вызывать следующие функции:
-
Функции инициализации интерпретатора:
Py_Initialize()Py_InitializeEx()Py_InitializeFromConfig()Py_BytesMain()Py_Main()- функции предварительной инициализации среды выполнения, описанные в разделе Конфигурация инициализации Python
-
Функции конфигурации:
PyImport_AppendInittab()PyImport_ExtendInittab()PyInitFrozenExtensions()PyMem_SetAllocator()PyMem_SetupDebugHooks()PyObject_SetArenaAllocator()Py_SetProgramName()Py_SetPythonHome()PySys_ResetWarnOptions()- функции конфигурации, описанные в разделе Конфигурация инициализации Python
-
Информационные функции:
-
Вспомогательные средства:
Py_DecodeLocale()- функции предоставления сведений о состоянии и вспомогательные функции, описанные в разделе Конфигурация инициализации Python
-
Аллокаторы памяти:
-
Синхронизация:
Примечание
Несмотря на кажущееся сходство с некоторыми из перечисленных выше функций, следующие функции не следует вызывать до инициализации интерпретатора: Py_EncodeLocale(), Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), Py_GetProgramFullPath(), Py_GetPythonHome(), Py_GetProgramName(), PyEval_InitThreads() и Py_RunMain().
Глобальные переменные конфигурации
В Python есть переменные глобальной конфигурации, управляющие различными возможностями и параметрами. По умолчанию этими флагами управляют параметры командной строки.
Если флаг задаётся параметром, его значение равно числу раз, когда этот параметр был указан. Например, -b устанавливает Py_BytesWarningFlag в значение 1, а -bb устанавливает Py_BytesWarningFlag в значение 2.
-
int Py_BytesWarningFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.bytes_warning, см. раздел Конфигурация инициализации Python.Выдавать предупреждение при сравнении
bytesилиbytearrayсstr, а такжеbytesсint. Если значение больше или равно2, выдавать ошибку.Задаётся параметром
-b.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_DebugFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.parser_debug, см. раздел Конфигурация инициализации Python.Включить вывод отладочной информации парсера (только для опытных пользователей; зависит от параметров компиляции).
Задаётся параметром
-dи переменной средыPYTHONDEBUG.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_DontWriteBytecodeFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.write_bytecode, см. раздел Конфигурация инициализации Python.Если значение не равно нулю, Python не будет записывать файлы
.pycпри импорте исходных модулей.Задаётся параметром
-Bи переменной средыPYTHONDONTWRITEBYTECODE.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_FrozenFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.pathconfig_warnings, см. раздел Конфигурация инициализации Python.Подавлять сообщения об ошибках при вычислении пути поиска модулей в
Py_GetPath().Закрытый флаг, используемый программами
_freeze_moduleиfrozenmain.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_HashRandomizationFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.hash_seedиPyConfig.use_hash_seed, см. раздел Конфигурация инициализации Python.Устанавливается в значение
1, если переменная средыPYTHONHASHSEEDзадана непустой строкой.Если значение флага не равно нулю, для инициализации секретного начального значения хеша считывается переменная среды
PYTHONHASHSEED.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_IgnoreEnvironmentFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.use_environment, см. раздел Конфигурация инициализации Python.Игнорировать все переменные среды
PYTHON*, напримерPYTHONPATHиPYTHONHOME, если они заданы.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_InspectFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.inspect, см. раздел Конфигурация инициализации Python.Если скрипт передан в качестве первого аргумента или используется параметр
-c, после выполнения скрипта или команды перейти в интерактивный режим, даже еслиsys.stdinне выглядит как терминал.Задаётся параметром
-iи переменной средыPYTHONINSPECT.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_InteractiveFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.interactive, см. раздел Конфигурация инициализации Python.Задаётся параметром
-i.Устарело с версии 3.12, будет удалено в версии 3.15.
-
int Py_IsolatedFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.isolated, см. раздел Конфигурация инициализации Python.Запускать Python в изолированном режиме. В изолированном режиме
sys.pathне содержит ни каталог скрипта, ни каталог пользовательских site-packages.Задаётся параметром
-I.Добавлено в версии 3.4.
Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_LegacyWindowsFSEncodingFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyPreConfig.legacy_windows_fs_encoding, см. раздел Конфигурация инициализации Python.Если значение флага не равно нулю, для кодировки файловой системы и обработчика ошибок используется кодировка
mbcsс обработчиком ошибокreplaceвместо кодировки UTF-8 с обработчиком ошибокsurrogatepass.Устанавливается в значение
1, если переменная средыPYTHONLEGACYWINDOWSFSENCODINGзадана непустой строкой.Подробности см. в PEP 529.
Доступность: Windows.
Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_LegacyWindowsStdioFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.legacy_windows_stdio, см. раздел Конфигурация инициализации Python.Если значение флага не равно нулю, для стандартных потоков
sysвместоio._WindowsConsoleIOиспользуетсяio.FileIO.Устанавливается в значение
1, если переменная средыPYTHONLEGACYWINDOWSSTDIOзадана непустой строкой.Подробности см. в PEP 528.
Доступность: Windows.
Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_NoSiteFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.site_import, см. раздел Конфигурация инициализации Python.Отключить импорт модуля
siteи связанные с ним измененияsys.path, зависящие от окружения сайта. Эти изменения также отключаются, еслиsiteявно импортируется позднее (вызовитеsite.main(), если хотите выполнить эти действия).Задаётся параметром
-S.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_NoUserSiteDirectory -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.user_site_directory, см. раздел Конфигурация инициализации Python.Не добавлять
user site-packages directoryвsys.path.Задаётся параметрами
-sи-I, а также переменной средыPYTHONNOUSERSITE.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_OptimizeFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.optimization_level, см. раздел Конфигурация инициализации Python.Задаётся параметром
-Oи переменной средыPYTHONOPTIMIZE.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_QuietFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.quiet, см. раздел Конфигурация инициализации Python.Не отображать сообщения об авторских правах и версии даже в интерактивном режиме.
Задаётся параметром
-q.Добавлено в версии 3.2.
Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_UnbufferedStdioFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.buffered_stdio, см. раздел Конфигурация инициализации Python.Принудительно отключить буферизацию потоков stdout и stderr.
Задаётся параметром
-uи переменной средыPYTHONUNBUFFERED.Устарело с версии 3.12, будет удалено в версии 3.14.
-
int Py_VerboseFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.verbose, см. раздел Конфигурация инициализации Python.Выводить сообщение при каждой инициализации модуля, указывая место (имя файла или встроенный модуль), из которого он загружен. Если значение больше или равно
2, выводить сообщение о каждом файле, проверяемом при поиске модуля. Также выводить сведения об очистке модулей при завершении работы.Задаётся параметром
-vи переменной средыPYTHONVERBOSE.Устарело с версии 3.12, будет удалено в версии 3.14.
Инициализация и завершение работы интерпретатора
-
void Py_Initialize() -
Часть стабильного ABI.
Инициализирует интерпретатор Python. В приложении, встраивающем Python, эту функцию следует вызвать до использования любых других функций Python/C API; исключения описаны в разделе До инициализации Python.
Эта функция инициализирует таблицу загруженных модулей (
sys.modules) и создает основные модулиbuiltins,__main__иsys. Она также инициализирует путь поиска модулей (sys.path). Она не устанавливаетsys.argv; для этого используйте API конфигурации инициализации Python. При повторном вызове функция ничего не делает (если перед этим не была вызванаPy_FinalizeEx()). Возвращаемого значения нет; сбой инициализации считается фатальной ошибкой.Чтобы настроить конфигурацию инициализации Python, используйте
Py_InitializeFromConfig().Примечание
В Windows функция меняет режим консоли с
O_TEXTнаO_BINARY, что также влияет на использование консоли не из Python с помощью C Runtime.
-
void Py_InitializeEx(int initsigs) -
Часть стабильного ABI.
Эта функция действует как
Py_Initialize(), если initsigs имеет значение1. Если initsigs имеет значение0, функция пропускает регистрацию обработчиков сигналов при инициализации, что может быть полезно, когда CPython встраивается в более крупное приложение.Чтобы настроить конфигурацию инициализации Python, используйте
Py_InitializeFromConfig().
-
PyStatus Py_InitializeFromConfig(const PyConfig *config) -
Инициализирует Python с конфигурацией config, как описано в разделе Инициализация с помощью PyConfig.
Подробные сведения о предварительной инициализации интерпретатора, заполнении структуры конфигурации среды выполнения и обработке возвращаемой структуры состояния приведены в разделе Конфигурация инициализации Python.
-
int Py_IsInitialized() -
Часть стабильного ABI.
Возвращает true (ненулевое значение), если интерпретатор Python инициализирован, и false (нулевое значение) в противном случае. После вызова
Py_FinalizeEx()функция возвращает false, пока снова не будет вызванаPy_Initialize().
-
int Py_IsFinalizing() -
Часть стабильного ABI начиная с версии 3.13.
Возвращает true (ненулевое значение), если основной интерпретатор Python завершает работу. В противном случае возвращает false (нулевое значение).
Добавлено в версии 3.13.
-
int Py_FinalizeEx() -
Часть стабильного ABI начиная с версии 3.6.
Отменяет все действия по инициализации, выполненные функцией
Py_Initialize()и последующими вызовами функций Python/C API, а также уничтожает все подынтерпретаторы (см.Py_NewInterpreter()ниже), созданные и не уничтоженные после последнего вызоваPy_Initialize(). В идеале это освобождает всю память, выделенную интерпретатором Python. При повторном вызове функция ничего не делает (если перед этим снова не была вызванаPy_Initialize()).Поскольку эта функция выполняет обратные действия по отношению к
Py_Initialize(), ее следует вызывать в том же потоке и при активном том же интерпретаторе. Это означает, что она должна вызываться в главном потоке для главного интерпретатора. Ее нельзя вызывать во время выполненияPy_RunMain().Обычно возвращаемое значение —
0. Если при завершении работы произошли ошибки (например, при сбросе буферизованных данных), возвращается-1.Эта функция предусмотрена по нескольким причинам. Встраивающему приложению может потребоваться перезапустить Python без перезапуска самого приложения. Приложению, загрузившему интерпретатор Python из динамически загружаемой библиотеки (или DLL), может потребоваться освободить всю выделенную Python память перед выгрузкой DLL. При поиске утечек памяти в приложении разработчику может понадобиться освободить всю память, выделенную Python, перед завершением приложения.
Ошибки и предостережения: Модули и объекты в модулях уничтожаются в случайном порядке; из-за этого деструкторы (методы
__del__()) могут завершиться с ошибкой, если они зависят от других объектов (даже функций) или модулей. Динамически загруженные Python модули расширения не выгружаются. Небольшие объемы памяти, выделенной интерпретатором Python, могут остаться неосвобожденными (если вы обнаружили утечку, сообщите о ней). Память, занятая циклическими ссылками между объектами, не освобождается. Некоторая память, выделенная модулями расширения, может остаться неосвобожденной. Некоторые расширения могут работать неправильно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение несколько раз вызываетPy_Initialize()иPy_FinalizeEx(). Нельзя рекурсивно вызыватьPy_FinalizeEx()из самой этой функции. Поэтому ее не должен вызывать код, который может выполняться в ходе завершения работы интерпретатора, например обработчикиatexit, финализаторы объектов или любой код, выполняемый при сбросе файлов stdout и stderr.Вызывает событие аудита
cpython._PySys_ClearAuditHooksбез аргументов.Добавлено в версии 3.6.
-
void Py_Finalize() -
Часть стабильного ABI.
Это обратно совместимая версия
Py_FinalizeEx(), которая игнорирует возвращаемое значение.
-
int Py_BytesMain(int argc, char **argv) -
Часть стабильного ABI начиная с версии 3.8.
Похожа на
Py_Main(), но argv представляет собой массив байтовых строк, что позволяет вызывающему приложению поручить декодирование текста среде выполнения CPython.Добавлено в версии 3.8.
-
int Py_Main(int argc, wchar_t **argv) -
Часть стабильного ABI.
Главная программа стандартного интерпретатора, выполняющая полный цикл инициализации и завершения работы, а также дополнительные действия для чтения параметров конфигурации из окружения и командной строки и последующего выполнения
__main__в соответствии с разделом Командная строка.Эта функция доступна программам, которым требуется поддержка полного интерфейса командной строки CPython, а не только встраивание среды выполнения Python в более крупное приложение.
Параметры argc и argv аналогичны параметрам, передаваемым функции
main()программы на C, за исключением того, что элементы argv сначала преобразуются вwchar_tс помощьюPy_DecodeLocale(). Также важно отметить, что элементы списка аргументов могут быть изменены так, чтобы указывать на другие строки, а не на переданные (содержимое строк, на которые указывает список аргументов, при этом не изменяется).Если список аргументов не соответствует допустимой командной строке Python, возвращается
2, в противном случае возвращается то же значение, что и уPy_RunMain().С точки зрения API конфигурации среды выполнения CPython, описанных в разделе конфигурации среды выполнения (без учета обработки ошибок),
Py_Mainприблизительно эквивалентна следующему:PyConfig config; PyConfig_InitPythonConfig(&config); PyConfig_SetArgv(&config, argc, argv); Py_InitializeFromConfig(&config); PyConfig_Clear(&config); Py_RunMain();
При обычном использовании встраивающее приложение вызывает эту функцию вместо непосредственного вызова
Py_Initialize(),Py_InitializeEx()илиPy_InitializeFromConfig(); все параметры применяются так, как описано в других разделах этой документации. Если же эта функция вызывается после предварительного вызова API инициализации среды выполнения, то набор обновляемых параметров конфигурации окружения и командной строки зависит от версии (поскольку возможность изменения уже установленных при первой инициализации среды выполнения параметров поддерживается не для всех настроек).
-
int Py_RunMain(void) -
Выполняет главный модуль в полностью сконфигурированной среде выполнения CPython.
Выполняет команду (
PyConfig.run_command), скрипт (PyConfig.run_filename) или модуль (PyConfig.run_module), указанный в командной строке или конфигурации. Если ни одно из этих значений не задано, запускает интерактивную командную строку Python (REPL), используя глобальное пространство имен модуля__main__.Если
PyConfig.inspectне задан (значение по умолчанию), возвращаемым значением будет0, если интерпретатор завершился нормально (то есть без исключения), код завершения необработанного исключенияSystemExitили1для любого другого необработанного исключения.Если задан
PyConfig.inspect(например, при использовании параметра-i), после завершения работы интерпретатора функция не возвращает управление, а продолжает выполнение в интерактивной командной строке Python (REPL), используя глобальное пространство имен модуля__main__. Если интерпретатор завершился с исключением, оно немедленно вызывается в сеансе REPL. Тогда возвращаемое значение функции определяется способом завершения сеанса REPL:0,1или кодом завершения исключенияSystemExit, как описано выше.Эта функция всегда завершает работу интерпретатора Python перед возвратом.
Пример настроенной версии Python, которая всегда работает в изолированном режиме с помощью
Py_RunMain(), приведен в разделе Конфигурация Python.
-
int PyUnstable_AtExit(PyInterpreterState *interp, void (*func)(void*), void *data) -
Это нестабильный API. Он может измениться без предупреждения в минорных выпусках.
Регистрирует функцию обратного вызова
atexitдля целевого интерпретатора interp. Она похожа наPy_AtExit(), но принимает явные параметры: интерпретатор и указатель на данные, передаваемые функции обратного вызова.Для interp должна быть захвачена блокировка GIL.
Добавлено в версии 3.13.
Параметры всего процесса
-
void Py_SetProgramName(const wchar_t *name) -
Часть стабильного ABI.
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.program_name, см. Конфигурация инициализации Python.Эту функцию следует вызывать до первого вызова
Py_Initialize(), если он вообще будет вызван. Она сообщает интерпретатору значение аргументаargv[0]функцииmain()программы (преобразованное в широкие символы). Это значение используется функциейPy_GetPath()и некоторыми другими функциями ниже для поиска библиотек времени выполнения Python относительно исполняемого файла интерпретатора. Значение по умолчанию —'python'. Аргумент должен указывать на строку широких символов с завершающим нулевым символом, размещённую в статической памяти; её содержимое не должно меняться в течение выполнения программы. Код интерпретатора Python не будет изменять содержимое этой области памяти.Используйте
Py_DecodeLocale(), чтобы декодировать строку байтов и получить строку wchar_t*.Устарело с версии 3.11.
-
wchar_t *Py_GetProgramName() -
Часть стабильного ABI.
Возвращает имя программы, заданное с помощью
PyConfig.program_name, или значение по умолчанию. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
sys.executable.
-
wchar_t *Py_GetPrefix() -
Часть стабильного ABI.
Возвращает префикс для установленных платформонезависимых файлов. Он определяется по ряду сложных правил на основе имени программы, заданного с помощью
PyConfig.program_name, и некоторых переменных среды; например, если имя программы —'/usr/local/bin/python', префикс —'/usr/local'. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это соответствует переменной prefix в корневомMakefileи аргументу--prefixскрипта configure во время сборки. Это значение доступно коду Python какsys.base_prefix. Оно полезно только в Unix. См. также следующую функцию.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
sys.base_prefixилиsys.prefix, если требуется поддержка виртуальных окружений.
-
wchar_t *Py_GetExecPrefix() -
Часть стабильного ABI.
Возвращает exec-префикс для установленных платформозависимых файлов. Он определяется по ряду сложных правил на основе имени программы, заданного с помощью
PyConfig.program_name, и некоторых переменных среды; например, если имя программы —'/usr/local/bin/python', exec-префикс —'/usr/local'. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это соответствует переменной exec_prefix в корневомMakefileи аргументу--exec-prefixскрипта configure во время сборки. Это значение доступно коду Python какsys.base_exec_prefix. Оно полезно только в Unix.Предыстория: exec-префикс отличается от префикса, если платформозависимые файлы (например, исполняемые файлы и разделяемые библиотеки) установлены в другом дереве каталогов. При типичной установке платформозависимые файлы могут быть установлены в подкаталог
/usr/local/plat, а платформонезависимые — в/usr/local.В общем случае платформа представляет собой сочетание аппаратной и программной среды; например, компьютеры Sparc под управлением операционной системы Solaris 2.x считаются одной платформой, компьютеры Intel под управлением Solaris 2.x — другой, а компьютеры Intel под управлением Linux — ещё одной. Разные основные версии одной операционной системы обычно также образуют разные платформы. С операционными системами, отличными от Unix, всё иначе: стратегии установки в них настолько отличаются, что префикс и exec-префикс не имеют смысла и устанавливаются в пустую строку. Обратите внимание, что скомпилированные файлы байт-кода Python являются платформонезависимыми (но зависят от версии Python, которой они были скомпилированы!).
Системные администраторы знают, как настроить программы mount или automount, чтобы совместно использовать
/usr/localмежду платформами, оставив при этом/usr/local/platотдельной файловой системой для каждой платформы.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
sys.base_exec_prefixилиsys.exec_prefix, если требуется поддержка виртуальных окружений.
-
wchar_t *Py_GetProgramFullPath() -
Часть стабильного ABI.
Возвращает полное имя исполняемого файла Python; оно вычисляется как побочный эффект определения пути поиска модулей по умолчанию на основе имени программы (заданного с помощью
PyConfig.program_name). Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python какsys.executable.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
sys.executable.
-
wchar_t *Py_GetPath() -
Часть стабильного ABI.
Возвращает путь поиска модулей по умолчанию; он вычисляется на основе имени программы (заданного с помощью
PyConfig.program_name) и некоторых переменных среды. Возвращённая строка состоит из последовательности имён каталогов, разделённых символом-разделителем, зависящим от платформы. В Unix и macOS символ-разделитель —':', в Windows —';'. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Списокsys.pathинициализируется этим значением при запуске интерпретатора; позднее его можно (и обычно так и делают) изменить, чтобы поменять путь поиска модулей.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
sys.path.
-
const char *Py_GetVersion() -
Часть стабильного ABI.
Возвращает версию этого интерпретатора Python. Эта строка выглядит примерно так:
"3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"
Первое слово (до первого пробела) — текущая версия Python; первые символы обозначают основную и дополнительную версии, разделённые точкой. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python как
sys.version.См. также константу
Py_Version.
-
const char *Py_GetPlatform() -
Часть стабильного ABI.
Возвращает идентификатор текущей платформы. В Unix он формируется из «официального» названия операционной системы, приведённого к нижнему регистру, за которым следует номер основной версии; например, для Solaris 2.x, также известной как SunOS 5.x, значение равно
'sunos5'. В macOS это'darwin'. В Windows это'win'. Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python какsys.platform.
-
const char *Py_GetCopyright() -
Часть стабильного ABI.
Возвращает официальную строку об авторских правах для текущей версии Python, например:
'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python как
sys.copyright.
-
const char *Py_GetCompiler() -
Часть стабильного ABI.
Возвращает указание на компилятор, использованный для сборки текущей версии Python, в квадратных скобках, например:
"[GCC 2.7.2.2]"
Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python как часть переменной
sys.version.
-
const char *Py_GetBuildInfo() -
Часть стабильного ABI.
Возвращает сведения о порядковом номере, а также дате и времени сборки текущего экземпляра интерпретатора Python, например:
"#67, Aug 1 1997, 22:34:28"
Возвращённая строка указывает на статическую область памяти; вызывающий код не должен изменять её значение. Это значение доступно коду Python как часть переменной
sys.version.
-
void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) -
Часть стабильного ABI.
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.argv,PyConfig.parse_argvиPyConfig.safe_path, см. Конфигурация инициализации Python.Задаёт
sys.argvна основе argc и argv. Эти параметры похожи на передаваемые функцииmain()программы, но первый элемент должен указывать на запускаемый файл скрипта, а не на исполняемый файл, содержащий интерпретатор Python. Если скрипт запускаться не будет, первый элемент argv может быть пустой строкой. Если этой функции не удаётся инициализироватьsys.argv, с помощьюPy_FatalError()сигнализируется критическая ошибка.Если updatepath равен нулю, функция делает только это. Если updatepath не равен нулю, функция также изменяет
sys.pathв соответствии со следующим алгоритмом:- Если в
argv[0]передано имя существующего скрипта, абсолютный путь к каталогу, в котором находится скрипт, добавляется в началоsys.path. - В противном случае (то есть если argc равно
0илиargv[0]не указывает на имя существующего файла) в началоsys.pathдобавляется пустая строка, что эквивалентно добавлению в начало текущего рабочего каталога (".").
Используйте
Py_DecodeLocale(), чтобы декодировать строку байтов и получить строку wchar_t*.См. также элементы
PyConfig.orig_argvиPyConfig.argvв разделе Конфигурация инициализации Python.Примечание
Рекомендуется, чтобы приложения, встраивающие интерпретатор Python для целей, отличных от выполнения одного скрипта, передавали
0в качестве updatepath и при необходимости самостоятельно изменялиsys.path. См. CVE 2008-5983.В версиях до 3.1.3 такого же эффекта можно добиться, вручную удалив первый элемент
sys.pathпосле вызоваPySys_SetArgv(), например, так:PyRun_SimpleString("import sys; sys.path.pop(0)\n");Добавлено в версии 3.1.3.
Устарело с версии 3.11.
- Если в
-
void PySys_SetArgv(int argc, wchar_t **argv) -
Часть стабильного ABI.
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.argvиPyConfig.parse_argv, см. Конфигурация инициализации Python.Эта функция работает как
PySys_SetArgvEx(), если для updatepath задано значение1, за исключением случаев, когда интерпретатор python запущен с параметром-I.Используйте
Py_DecodeLocale(), чтобы декодировать строку байтов и получить строку wchar_t*.См. также элементы
PyConfig.orig_argvиPyConfig.argvв разделе Конфигурация инициализации Python.Изменено в версии 3.4: Значение updatepath зависит от
-I.Устарело с версии 3.11.
-
void Py_SetPythonHome(const wchar_t *home) -
Часть стабильного ABI.
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.home, см. Конфигурация инициализации Python.Задаёт каталог «home» по умолчанию, то есть расположение стандартных библиотек Python. Значение строки аргумента описано в
PYTHONHOME.Аргумент должен указывать на строку символов с завершающим нулевым символом, размещённую в статической памяти; её содержимое не должно меняться в течение выполнения программы. Код интерпретатора Python не будет изменять содержимое этой области памяти.
Используйте
Py_DecodeLocale(), чтобы декодировать строку байтов и получить строку wchar_t*.Устарело с версии 3.11.
-
wchar_t *Py_GetPythonHome() -
Часть стабильного ABI.
Возвращает «home» по умолчанию, то есть значение, заданное с помощью
PyConfig.home, либо значение переменной средыPYTHONHOME, если она задана.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().Устарело с версии 3.13, будет удалено в версии 3.15: Вместо этого используйте
PyConfig.homeили переменную средыPYTHONHOME.
Состояние потока и глобальная блокировка интерпретатора
Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python существует глобальная блокировка, называемая глобальной блокировкой интерпретатора или GIL, которую текущий поток должен удерживать, прежде чем безопасно обращаться к объектам Python. Без этой блокировки даже простейшие операции могут вызвать проблемы в многопоточной программе: например, если два потока одновременно увеличивают счётчик ссылок одного объекта, его значение в итоге может увеличиться только на единицу, а не на два.
Поэтому действует правило: работать с объектами Python или вызывать функции Python/C API может только поток, захвативший GIL. Чтобы имитировать параллельное выполнение, интерпретатор регулярно пытается переключать потоки (см. sys.setswitchinterval()). Блокировка также освобождается перед потенциально блокирующими операциями ввода-вывода, такими как чтение или запись файла, чтобы в это время могли выполняться другие потоки Python.
Интерпретатор Python хранит некоторые сведения о конкретном потоке в структуре данных под названием PyThreadState. Кроме того, имеется глобальная переменная, указывающая на текущее состояние потока PyThreadState: получить его можно с помощью PyThreadState_Get().
Освобождение GIL в коде расширения
Большая часть кода расширений, работающего с GIL, имеет следующую простую структуру:
Save the thread state in a local variable. Release the global interpreter lock. ... Do some blocking I/O operation ... Reacquire the global interpreter lock. Restore the thread state from the local variable.
Это настолько распространённый шаблон, что для его упрощения существуют две макрокоманды:
Py_BEGIN_ALLOW_THREADS ... Do some blocking I/O operation ... Py_END_ALLOW_THREADS
Макрокоманда Py_BEGIN_ALLOW_THREADS открывает новый блок и объявляет скрытую локальную переменную; макрокоманда Py_END_ALLOW_THREADS закрывает блок.
Приведённый выше блок раскрывается в следующий код:
PyThreadState *_save; _save = PyEval_SaveThread(); ... Do some blocking I/O operation ... PyEval_RestoreThread(_save);
Вот как работают эти функции: глобальная блокировка интерпретатора защищает указатель на текущее состояние потока. При освобождении блокировки и сохранении состояния указатель на текущее состояние потока необходимо получить до освобождения блокировки (поскольку другой поток может немедленно захватить блокировку и записать своё состояние потока в глобальную переменную). И наоборот, при захвате блокировки и восстановлении состояния потока блокировку необходимо захватить до записи указателя на состояние потока.
Примечание
Чаще всего GIL освобождают при вызове системных функций ввода-вывода, однако это также может быть полезно перед вызовом длительных вычислений, которым не требуется доступ к объектам Python, например сжатия или криптографических функций, работающих с буферами памяти. Например, стандартные модули zlib и hashlib освобождают GIL при сжатии или хешировании данных.
Потоки, созданные не Python
При создании потоков с помощью специальных API Python (например, модуля threading) им автоматически назначается состояние потока, поэтому приведённый выше код корректен. Однако потоки, созданные из C (например, сторонней библиотекой с собственным управлением потоками), не удерживают GIL, и для них не создана структура состояния потока.
Если из таких потоков требуется вызывать код Python (часто это часть API обратного вызова, предоставляемого упомянутой сторонней библиотекой), сначала необходимо зарегистрировать эти потоки в интерпретаторе: создать структуру данных состояния потока, затем захватить GIL и, наконец, сохранить указатель на состояние потока. После этого можно использовать Python/C API. По завершении следует сбросить указатель на состояние потока, освободить GIL и, наконец, освободить структуру данных состояния потока.
Функции PyGILState_Ensure() и PyGILState_Release() автоматически выполняют все перечисленные действия. Типичный шаблон вызова Python из потока C выглядит так:
PyGILState_STATE gstate; gstate = PyGILState_Ensure(); /* Perform Python actions here. */ result = CallSomeFunction(); /* evaluate result or handle exception */ /* Release the thread. No Python API allowed beyond this point. */ PyGILState_Release(gstate);
Обратите внимание: функции PyGILState_* предполагают наличие только одного глобального интерпретатора (создаваемого автоматически функцией Py_Initialize()). Python поддерживает создание дополнительных интерпретаторов (с помощью Py_NewInterpreter()), однако совместное использование нескольких интерпретаторов и API PyGILState_* не поддерживается.
Предостережения при вызове fork()
Ещё один важный момент, касающийся потоков, — их поведение при вызове C-функции fork(). В большинстве систем с fork() после создания дочернего процесса с помощью fork() остаётся только поток, вызвавший fork. Это напрямую влияет как на порядок работы с блокировками, так и на всё сохранённое состояние среды выполнения CPython.
Поскольку остаётся только «текущий» поток, блокировки, удерживаемые другими потоками, никогда не будут освобождены. В случае os.fork() Python решает эту проблему, захватывая используемые им внутренние блокировки перед вызовом fork и освобождая их после него. Кроме того, в дочернем процессе он сбрасывает все объекты блокировок. При расширении или встраивании Python невозможно сообщить Python о дополнительных блокировках (не относящихся к Python), которые необходимо захватить перед fork или сбросить после него. Для этого пришлось бы использовать средства ОС, такие как pthread_atfork(). Кроме того, при расширении или встраивании Python непосредственный вызов fork() вместо вызова через os.fork() (с последующим возвратом в Python или вызовом кода Python) может привести к взаимной блокировке: одну из внутренних блокировок Python может удерживать поток, который после fork перестал существовать. Функция PyOS_AfterFork_Child() пытается сбросить необходимые блокировки, но не всегда может это сделать.
Исчезновение всех остальных потоков также означает, что состояние среды выполнения CPython необходимо корректно очистить; это делает os.fork(). Очистка включает финализацию всех остальных объектов PyThreadState, принадлежащих текущему интерпретатору, и всех остальных объектов PyInterpreterState. В связи с этим, а также с особенностями «основного» интерпретатора, fork() следует вызывать только в «основном» потоке этого интерпретатора — том, в котором изначально была инициализирована глобальная среда выполнения CPython. Единственное исключение — если сразу после этого будет вызвана функция exec().
Предостережения при финализации среды выполнения
На позднем этапе завершения работы интерпретатора, после попытки дождаться завершения недемонических потоков (хотя эту попытку может прервать KeyboardInterrupt) и выполнения функций atexit, среда выполнения помечается как финализируемая: Py_IsFinalizing() и sys.is_finalizing() возвращают true. На этом этапе захватывать GIL разрешено только потоку финализации, инициировавшему финализацию (обычно основному потоку).
Если во время финализации любой поток, кроме потока финализации, попытается захватить GIL — явно с помощью PyGILState_Ensure(), Py_END_ALLOW_THREADS, PyEval_AcquireThread() или PyEval_AcquireLock() либо неявно, когда интерпретатор попытается повторно захватить его после освобождения, — поток перейдёт в постоянно заблокированное состояние, в котором останется до завершения программы. В большинстве случаев это безвредно, но может привести к взаимной блокировке, если на более позднем этапе финализации будет предпринята попытка захватить блокировку, принадлежащую заблокированному потоку, или иным образом ожидать его завершения.
Грубо? Да. Это предотвращает случайные сбои и/или неожиданное пропускание финализации C++ на более ранних этапах стека вызовов, которые происходили в CPython 3.13.7 и более ранних версиях, когда такие потоки здесь принудительно завершались. В API среды выполнения CPython для захвата GIL никогда не предусматривались механизмы сообщения об ошибках или их обработки во время захвата GIL, которые позволили бы корректно выйти из этой ситуации. Для изменения этого поведения потребовались бы новые стабильные API C и переписывание большей части кода C в экосистеме CPython с добавлением обработки ошибок.
Высокоуровневый API
При написании расширений на C или встраивании интерпретатора Python чаще всего используются следующие типы и функции:
-
type PyInterpreterState -
Часть ограниченного API (в виде непрозрачной структуры).
Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, используют общие средства управления модулями и некоторые другие внутренние объекты. У этой структуры нет общедоступных членов.
Изначально потоки, принадлежащие разным интерпретаторам, не имеют ничего общего, кроме состояния процесса, например доступной памяти, открытых файловых дескрипторов и тому подобного. Глобальная блокировка интерпретатора также является общей для всех потоков независимо от того, к какому интерпретатору они принадлежат.
Изменено в версии 3.12: PEP 684 ввёл возможность использовать отдельный GIL для каждого интерпретатора. См.
Py_NewInterpreterFromConfig().
-
type PyThreadState -
Часть ограниченного API (в виде непрозрачной структуры).
Эта структура данных представляет состояние одного потока. Единственный общедоступный элемент данных:
-
PyInterpreterState *interp -
Состояние интерпретатора для этого потока.
-
-
void PyEval_InitThreads() -
Часть стабильного ABI.
Устаревшая функция, которая ничего не делает.
В Python 3.6 и более ранних версиях эта функция создавала GIL, если он ещё не существовал.
Изменено в версии 3.9: Теперь функция ничего не делает.
Изменено в версии 3.7: Теперь эту функцию вызывает
Py_Initialize(), поэтому вызывать её самостоятельно больше не нужно.Изменено в версии 3.2: Теперь эту функцию нельзя вызывать до
Py_Initialize().Устарела с версии 3.9.
-
PyThreadState *PyEval_SaveThread() -
Часть стабильного ABI.
Освобождает глобальную блокировку интерпретатора (если она была создана) и сбрасывает состояние потока в
NULL, возвращая предыдущее состояние потока (которое не равноNULL). Если блокировка была создана, текущий поток должен её удерживать.
-
void PyEval_RestoreThread(PyThreadState *tstate) -
Часть стабильного ABI.
Захватывает глобальную блокировку интерпретатора (если она была создана) и устанавливает состояние потока в tstate, которое не должно быть равно
NULL. Если блокировка была создана, текущий поток не должен её удерживать, иначе возникнет взаимная блокировка.Примечание
Вызов этой функции из потока во время финализации среды выполнения заблокирует поток до завершения программы, даже если этот поток был создан не Python. Подробности см. в разделе «Предостережения при финализации среды выполнения».
Изменено в версии 3.13.8: Если функция вызвана во время финализации интерпретатора, она блокирует текущий поток, а не завершает его.
-
PyThreadState *PyThreadState_Get() -
Часть стабильного ABI.
Возвращает текущее состояние потока. Глобальная блокировка интерпретатора должна быть захвачена. Если текущее состояние потока равно
NULL, функция вызывает фатальную ошибку (поэтому вызывающему коду не нужно проверять наличиеNULL).См. также
PyThreadState_GetUnchecked().
-
PyThreadState *PyThreadState_GetUnchecked() -
Похожа на
PyThreadState_Get(), но не завершает процесс с фатальной ошибкой, если результат равен NULL. Вызывающий код должен самостоятельно проверить, равен ли результат NULL.Добавлена в версии 3.13: В Python с 3.5 по 3.12 эта функция была закрытой и называлась
_PyThreadState_UncheckedGet().
-
PyThreadState *PyThreadState_Swap(PyThreadState *tstate) -
Часть стабильного ABI.
Заменяет текущее состояние потока состоянием, переданным аргументом tstate, который может быть равен
NULL.Удерживать GIL не требуется, однако после возврата он будет захвачен, если tstate не равен
NULL.
Следующие функции используют локальное хранилище потока и несовместимы с подинтерпретаторами:
-
PyGILState_STATE PyGILState_Ensure() -
Часть стабильного ABI.
Гарантирует, что текущий поток готов вызывать Python C API независимо от текущего состояния Python и глобальной блокировки интерпретатора. Поток может вызывать эту функцию сколько угодно раз, если каждый вызов сопровождается вызовом
PyGILState_Release(). В общем случае между вызовамиPyGILState_Ensure()иPyGILState_Release()можно использовать другие API для работы с потоками, если перед вызовом Release() состояние потока восстановлено до исходного. Например, допустимо обычное использование макрокомандPy_BEGIN_ALLOW_THREADSиPy_END_ALLOW_THREADS.Возвращаемое значение — непрозрачный «дескриптор» состояния потока на момент вызова
PyGILState_Ensure(). Его необходимо передать вPyGILState_Release(), чтобы Python вернулся в то же состояние. Хотя рекурсивные вызовы разрешены, эти дескрипторы нельзя использовать совместно: каждый отдельный вызовPyGILState_Ensure()должен сохранить дескриптор для соответствующего вызоваPyGILState_Release().После возврата функции текущий поток будет удерживать GIL и сможет вызывать произвольный код Python. В случае сбоя возникает фатальная ошибка.
Примечание
Вызов этой функции из потока во время финализации среды выполнения заблокирует поток до завершения программы, даже если этот поток был создан не Python. Подробности см. в разделе «Предостережения при финализации среды выполнения».
Изменено в версии 3.13.8: Если функция вызвана во время финализации интерпретатора, она блокирует текущий поток, а не завершает его.
-
void PyGILState_Release(PyGILState_STATE) -
Часть стабильного ABI.
Освобождает все ранее полученные ресурсы. После этого вызова состояние Python будет таким же, каким оно было до соответствующего вызова
PyGILState_Ensure()(однако вызывающий код обычно не знает этого состояния, поэтому и используется API GILState).Каждому вызову
PyGILState_Ensure()должен соответствовать вызовPyGILState_Release()в том же потоке.
-
PyThreadState *PyGILState_GetThisThreadState() -
Часть стабильного ABI.
Возвращает текущее состояние этого потока. Может вернуть
NULL, если в текущем потоке не использовался API GILState. Обратите внимание, что у главного потока всегда есть такое состояние потока, даже если в нём не вызывалась функция автоматической настройки состояния потока. В основном эта функция предназначена для вспомогательной диагностики.
-
int PyGILState_Check() -
Возвращает
1, если текущий поток удерживает GIL, и0в противном случае. Эту функцию можно вызывать из любого потока в любое время. Она вернёт1только в том случае, если состояние потока Python было инициализировано и поток в данный момент удерживает GIL. В основном эта функция предназначена для вспомогательной диагностики. Она может быть полезна, например, в контекстах обратного вызова или функциях выделения памяти: зная, что GIL захвачен, вызывающий код может выполнить важные действия или изменить своё поведение.Добавлена в версии 3.4.
Следующие макрокоманды обычно используют без завершающей точки с запятой; примеры использования можно найти в исходном дистрибутиве Python.
-
Py_BEGIN_ALLOW_THREADS -
Часть стабильного ABI.
Эта макрокоманда раскрывается в
{ PyThreadState *_save; _save = PyEval_SaveThread();. Обратите внимание, что она содержит открывающую фигурную скобку; ей должна соответствовать следующая макрокомандаPy_END_ALLOW_THREADS. Дополнительные сведения об этой макрокоманде см. выше.
-
Py_END_ALLOW_THREADS -
Часть стабильного ABI.
Эта макрокоманда раскрывается в
PyEval_RestoreThread(_save); }. Обратите внимание, что она содержит закрывающую фигурную скобку; ей должна соответствовать предшествующая макрокомандаPy_BEGIN_ALLOW_THREADS. Дополнительные сведения об этой макрокоманде см. выше.
-
Py_BLOCK_THREADS -
Часть стабильного ABI.
Эта макрокоманда раскрывается в
PyEval_RestoreThread(_save);: она эквивалентнаPy_END_ALLOW_THREADSбез закрывающей фигурной скобки.
-
Py_UNBLOCK_THREADS -
Часть стабильного ABI.
Эта макрокоманда раскрывается в
_save = PyEval_SaveThread();: она эквивалентнаPy_BEGIN_ALLOW_THREADSбез открывающей фигурной скобки и объявления переменной.
Низкоуровневый API
Все перечисленные ниже функции необходимо вызывать после Py_Initialize().
Изменено в версии 3.7: Теперь Py_Initialize() инициализирует GIL.
-
PyInterpreterState *PyInterpreterState_New() -
Часть стабильного ABI.
Создаёт новый объект состояния интерпретатора. Глобальную блокировку интерпретатора удерживать не требуется, но её можно удерживать, если это необходимо для сериализации вызовов этой функции.
Вызывает событие аудита
cpython.PyInterpreterState_Newбез аргументов.
-
void PyInterpreterState_Clear(PyInterpreterState *interp) -
Часть стабильного ABI.
Сбрасывает всю информацию в объекте состояния интерпретатора. Глобальная блокировка интерпретатора должна быть удержана.
Вызывает событие аудита
cpython.PyInterpreterState_Clearбез аргументов.
-
void PyInterpreterState_Delete(PyInterpreterState *interp) -
Часть стабильного ABI.
Уничтожает объект состояния интерпретатора. Глобальную блокировку интерпретатора удерживать не требуется. Состояние интерпретатора должно быть сброшено предыдущим вызовом
PyInterpreterState_Clear().
-
PyThreadState *PyThreadState_New(PyInterpreterState *interp) -
Часть стабильного ABI.
Создаёт новый объект состояния потока, принадлежащий указанному объекту интерпретатора. Глобальную блокировку интерпретатора удерживать не требуется, но её можно удерживать, если это необходимо для сериализации вызовов этой функции.
-
void PyThreadState_Clear(PyThreadState *tstate) -
Часть стабильного ABI.
Сбрасывает всю информацию в объекте состояния потока. Глобальная блокировка интерпретатора должна быть удержана.
Изменено в версии 3.9: Теперь эта функция вызывает обратный вызов
PyThreadState.on_delete. Ранее он вызывался вPyThreadState_Delete().Изменено в версии 3.13: Обратный вызов
PyThreadState.on_deleteудалён.
-
void PyThreadState_Delete(PyThreadState *tstate) -
Часть стабильного ABI.
Уничтожает объект состояния потока. Глобальную блокировку интерпретатора удерживать не требуется. Состояние потока должно быть сброшено предыдущим вызовом
PyThreadState_Clear().
-
void PyThreadState_DeleteCurrent(void) -
Уничтожает текущее состояние потока и освобождает глобальную блокировку интерпретатора. Как и для
PyThreadState_Delete(), глобальная блокировка интерпретатора должна быть удержана. Состояние потока должно быть сброшено предыдущим вызовомPyThreadState_Clear().
-
PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate) -
Часть стабильного ABI начиная с версии 3.10.
Возвращает текущий кадр состояния потока Python tstate.
Возвращает сильную ссылку. Возвращает
NULL, если в данный момент не выполняется ни один кадр.См. также
PyEval_GetFrame().tstate не должен быть
NULL.Добавлено в версии 3.9.
-
uint64_t PyThreadState_GetID(PyThreadState *tstate) -
Часть стабильного ABI начиная с версии 3.10.
Возвращает уникальный идентификатор состояния потока Python tstate.
tstate не должен быть
NULL.Добавлено в версии 3.9.
-
PyInterpreterState *PyThreadState_GetInterpreter(PyThreadState *tstate) -
Часть стабильного ABI начиная с версии 3.10.
Возвращает интерпретатор состояния потока Python tstate.
tstate не должен быть
NULL.Добавлено в версии 3.9.
-
void PyThreadState_EnterTracing(PyThreadState *tstate) -
Приостанавливает трассировку и профилирование в состоянии потока Python tstate.
Возобновите их с помощью функции
PyThreadState_LeaveTracing().Добавлено в версии 3.11.
-
void PyThreadState_LeaveTracing(PyThreadState *tstate) -
Возобновляет трассировку и профилирование в состоянии потока Python tstate, приостановленные функцией
PyThreadState_EnterTracing().См. также функции
PyEval_SetTrace()иPyEval_SetProfile().Добавлено в версии 3.11.
-
PyInterpreterState *PyInterpreterState_Get(void) -
Часть стабильного ABI начиная с версии 3.9.
Возвращает текущий интерпретатор.
Вызывает фатальную ошибку, если нет текущего состояния потока Python или текущего интерпретатора. Эта функция не может вернуть NULL.
Вызывающий код должен удерживать GIL.
Добавлено в версии 3.9.
-
int64_t PyInterpreterState_GetID(PyInterpreterState *interp) -
Часть стабильного ABI начиная с версии 3.7.
Возвращает уникальный идентификатор интерпретатора. Если при этом произошла ошибка, возвращается
-1и устанавливается ошибка.Вызывающий код должен удерживать GIL.
Добавлено в версии 3.7.
-
PyObject *PyInterpreterState_GetDict(PyInterpreterState *interp) -
Возвращаемое значение: заимствованная ссылка. Часть стабильного ABI начиная с версии 3.8.
Возвращает словарь, в котором можно хранить данные, специфичные для интерпретатора. Если эта функция возвращает
NULL, исключение не возникло, и вызывающий код должен считать, что словарь для данных интерпретатора недоступен.Эта функция не заменяет
PyModule_GetState(), которую расширениям следует использовать для хранения информации о состоянии, специфичной для интерпретатора.Возвращаемый словарь заимствуется у интерпретатора и действителен до его завершения.
Добавлено в версии 3.8.
-
PyObject *PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *interp) -
Это нестабильный API. Он может измениться без предупреждения в минорных выпусках.
Возвращает сильную ссылку на объект модуля
__main__для указанного интерпретатора.Вызывающий код должен удерживать GIL.
Добавлено в версии 3.13.
-
typedef PyObject *(*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) -
Тип функции вычисления кадра.
Параметр throwflag используется методом
throw()генераторов: если он не равен нулю, обрабатывается текущее исключение.Изменено в версии 3.9: Теперь функция принимает параметр tstate.
Изменено в версии 3.11: Тип параметра frame изменён с
PyFrameObject*на_PyInterpreterFrame*.
-
_PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) -
Возвращает функцию вычисления кадра.
См. PEP 523 «Добавление API вычисления кадра в CPython».
Добавлено в версии 3.9.
-
void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame) -
Устанавливает функцию вычисления кадра.
См. PEP 523 «Добавление API вычисления кадра в CPython».
Добавлено в версии 3.9.
-
PyObject *PyThreadState_GetDict() -
Возвращаемое значение: заимствованная ссылка. Часть стабильного ABI.
Возвращает словарь, в котором расширения могут хранить информацию о состоянии, специфичную для потока. Каждому расширению следует использовать уникальный ключ для хранения состояния в словаре. Эту функцию можно вызывать, даже если текущее состояние потока недоступно. Если эта функция возвращает
NULL, исключение не возникло, и вызывающий код должен считать, что текущее состояние потока недоступно.
-
int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) -
Часть стабильного ABI.
Асинхронно вызывает исключение в потоке. Аргумент id — идентификатор целевого потока; exc — объект исключения, которое необходимо вызвать. Эта функция не забирает ссылки на exc. Чтобы избежать наивного неправильного использования, необходимо написать собственное расширение C для вызова этой функции. Вызывать её необходимо при удерживаемом GIL. Возвращает количество изменённых состояний потока; обычно оно равно единице, но будет равно нулю, если идентификатор потока не найден. Если exc равен
NULL, ожидающее исключение (если оно есть) для этого потока очищается. Исключения не возникают.Изменено в версии 3.7: Тип параметра id изменён с long на unsigned long.
-
void PyEval_AcquireThread(PyThreadState *tstate) -
Часть стабильного ABI.
Захватывает глобальную блокировку интерпретатора и устанавливает tstate в качестве текущего состояния потока. tstate не должен быть
NULL. Блокировка должна быть создана ранее. Если у этого потока блокировка уже есть, возникнет взаимная блокировка.Примечание
Если вызвать эту функцию из потока во время завершения работы среды выполнения, поток будет заблокирован до завершения программы, даже если он был создан не Python. Подробнее см. в разделе Предостережения относительно завершения работы среды выполнения.
Изменено в версии 3.8: Поведение приведено в соответствие с
PyEval_RestoreThread(),Py_END_ALLOW_THREADS()иPyGILState_Ensure(); при вызове во время завершения работы интерпретатора текущий поток завершается.Изменено в версии 3.13.8: При вызове во время завершения работы интерпретатора текущий поток блокируется, а не завершается.
PyEval_RestoreThread()— функция более высокого уровня, которая доступна всегда (даже если потоки не были инициализированы).
-
void PyEval_ReleaseThread(PyThreadState *tstate) -
Часть стабильного ABI.
Сбрасывает текущее состояние потока в
NULLи освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и удерживаться текущим потоком. Аргумент tstate, который не должен бытьNULL, используется только для проверки того, что он соответствует текущему состоянию потока; если это не так, выдаётся фатальная ошибка.PyEval_SaveThread()— функция более высокого уровня, которая доступна всегда (даже если потоки не были инициализированы).
Поддержка субинтерпретаторов
Хотя в большинстве случаев вы будете встраивать только один интерпретатор Python, бывают ситуации, когда в одном процессе и, возможно, даже в одном потоке необходимо создать несколько независимых интерпретаторов. Субинтерпретаторы позволяют это сделать.
«Главный» интерпретатор — это первый интерпретатор, созданный при инициализации среды выполнения. Обычно он является единственным интерпретатором Python в процессе. В отличие от субинтерпретаторов, главный интерпретатор несёт уникальные обязанности на уровне всего процесса, например обработку сигналов. Он также отвечает за выполнение кода во время инициализации среды выполнения и обычно является активным интерпретатором во время её завершения. Функция PyInterpreterState_Main() возвращает указатель на его состояние.
Переключаться между субинтерпретаторами можно с помощью функции PyThreadState_Swap(). Создавать и уничтожать их можно с помощью следующих функций:
-
type PyInterpreterConfig -
Структура, содержащая большинство параметров настройки субинтерпретатора. Её значения используются только в
Py_NewInterpreterFromConfig()и никогда не изменяются средой выполнения.Добавлено в версии 3.12.
Поля структуры:
-
int use_main_obmalloc -
Если значение равно
0, субинтерпретатор будет использовать собственное состояние распределителя памяти «объектов». В противном случае он будет использовать (совместно с главным интерпретатором) его состояние.Если значение равно
0, тоcheck_multi_interp_extensionsдолжно быть равно1(не нулю). Если значение равно1, тоgilне должно быть равноPyInterpreterConfig_OWN_GIL.
-
int allow_fork -
Если значение равно
0, среда выполнения не будет поддерживать создание ответвления процесса в каком-либо потоке, где в данный момент активен субинтерпретатор. В противном случае создание ответвлений не ограничено.Обратите внимание, что модуль
subprocessпродолжает работать, даже если создание ответвлений запрещено.
-
int allow_exec -
Если значение равно
0, среда выполнения не будет поддерживать замену текущего процесса посредством exec (например,os.execv()) в каком-либо потоке, где в данный момент активен субинтерпретатор. В противном случае использование exec не ограничено.Обратите внимание, что модуль
subprocessпродолжает работать, даже если exec запрещён.
-
int allow_threads -
Если значение равно
0, модульthreadingсубинтерпретатора не будет создавать потоки. В противном случае потоки разрешены.
-
int allow_daemon_threads -
Если значение равно
0, модульthreadingсубинтерпретатора не будет создавать потоки-демоны. В противном случае потоки-демоны разрешены (еслиallow_threadsне равно нулю).
-
int check_multi_interp_extensions -
Если значение равно
0, в любом потоке, где в данный момент активен субинтерпретатор, можно импортировать все модули расширений, включая устаревшие модули (с однофазной инициализацией). В противном случае можно импортировать только модули расширений с многофазной инициализацией (см. PEP 489). (См. такжеPy_mod_multiple_interpreters.)Значение должно быть
1(не нулём), еслиuse_main_obmallocравно0.
-
int gil -
Этот параметр определяет работу GIL субинтерпретатора. Он может принимать одно из следующих значений:
-
PyInterpreterConfig_DEFAULT_GIL -
Использовать значение по умолчанию (
PyInterpreterConfig_SHARED_GIL).
-
PyInterpreterConfig_SHARED_GIL -
Использовать GIL главного интерпретатора (совместно с ним).
-
PyInterpreterConfig_OWN_GIL -
Использовать собственный GIL субинтерпретатора.
Если значение равно
PyInterpreterConfig_OWN_GIL, тоPyInterpreterConfig.use_main_obmallocдолжно быть равно0. -
-
-
PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config) -
Создаёт новый субинтерпретатор. Это (почти) полностью отдельная среда для выполнения кода Python. В частности, у нового интерпретатора есть отдельные, независимые версии всех импортированных модулей, включая основные модули
builtins,__main__иsys. Таблица загруженных модулей (sys.modules) и путь поиска модулей (sys.path) также отдельные. В новой среде нет переменнойsys.argv. В ней есть новые файловые объекты стандартных потоков ввода-выводаsys.stdin,sys.stdoutиsys.stderr(однако они ссылаются на те же базовые файловые дескрипторы).Указанный параметр config задаёт параметры инициализации интерпретатора.
В случае успеха параметру tstate_p будет присвоено состояние первого потока, созданного в новом субинтерпретаторе. Это состояние потока создаётся в текущем состоянии потока. Обратите внимание, что фактический поток не создаётся; см. обсуждение состояний потоков ниже. Если создать новый интерпретатор не удастся, параметру tstate_p будет присвоено значение
NULL; исключение не устанавливается, поскольку состояние исключения хранится в текущем состоянии потока, а текущее состояние потока может отсутствовать.Как и перед вызовом всех остальных функций Python/C API, перед вызовом этой функции необходимо захватить глобальную блокировку интерпретатора; при возврате она по-прежнему будет захвачена. Аналогично, при входе должно быть установлено текущее состояние потока. В случае успеха возвращённое состояние потока будет установлено в качестве текущего. Если субинтерпретатор создаётся со своим GIL, GIL вызывающего интерпретатора будет освобождён. При возврате функции текущий поток будет удерживать GIL нового интерпретатора, а GIL предыдущего интерпретатора останется освобождённым.
Добавлено в версии 3.12.
Субинтерпретаторы работают наиболее эффективно, когда изолированы друг от друга и доступ к некоторым функциям ограничен:
PyInterpreterConfig config = { .use_main_obmalloc = 0, .allow_fork = 0, .allow_exec = 0, .allow_threads = 1, .allow_daemon_threads = 0, .check_multi_interp_extensions = 1, .gil = PyInterpreterConfig_OWN_GIL, }; PyThreadState *tstate = NULL; PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); if (PyStatus_Exception(status)) { Py_ExitStatusException(status); }Обратите внимание, что конфигурация используется лишь непродолжительное время и не изменяется. Во время инициализации значения конфигурации преобразуются в различные значения
PyInterpreterState. Копия конфигурации, доступная только для чтения, может храниться внутриPyInterpreterState.Модули расширений совместно используются (суб-)интерпретаторами следующим образом:
- Для модулей с многофазной инициализацией, например
PyModule_FromDefAndSpec(), для каждого интерпретатора создаётся и инициализируется отдельный объект модуля. Между этими объектами модулей совместно используются только статические и глобальные переменные уровня C. -
Для модулей с однофазной инициализацией, например
PyModule_Create(), при первом импорте конкретного расширения оно инициализируется обычным образом, а (поверхностная) копия словаря модуля сохраняется. Когда то же расширение импортируется другим (суб-)интерпретатором, новый модуль инициализируется и заполняется содержимым этой копии; функцияinitрасширения не вызывается. Таким образом, объекты в словаре модуля оказываются общими для нескольких (суб-)интерпретаторов, что может привести к нежелательному поведению (см. раздел Ошибки и предостережения ниже).Обратите внимание, что это отличается от ситуации, когда расширение импортируется после полной повторной инициализации интерпретатора вызовами
Py_FinalizeEx()иPy_Initialize(); в этом случае функцияinitmoduleрасширения вызывается снова. Как и при многофазной инициализации, это означает, что между этими модулями совместно используются только статические и глобальные переменные уровня C.
- Для модулей с многофазной инициализацией, например
-
PyThreadState *Py_NewInterpreter(void) -
Часть стабильного ABI.
Создаёт новый субинтерпретатор. По сути, это лишь обёртка над
Py_NewInterpreterFromConfig()с конфигурацией, сохраняющей прежнее поведение. В результате создаётся неизолированный субинтерпретатор, который использует GIL главного интерпретатора совместно с ним, разрешает создание ответвлений и exec, разрешает потоки-демоны и модули с однофазной инициализацией.
-
void Py_EndInterpreter(PyThreadState *tstate) -
Часть стабильного ABI.
Уничтожает (суб-)интерпретатор, представленный указанным состоянием потока. Указанное состояние потока должно быть текущим. См. обсуждение состояний потоков ниже. После возврата вызова текущее состояние потока равно
NULL. Все состояния потоков, связанные с этим интерпретатором, уничтожаются. Перед вызовом этой функции необходимо захватить глобальную блокировку интерпретатора, для которого выполняется вызов. При возврате GIL не захвачен.Py_FinalizeEx()уничтожит все субинтерпретаторы, которые к тому моменту не были явно уничтожены.
Отдельный GIL для каждого интерпретатора
С помощью Py_NewInterpreterFromConfig() можно создать субинтерпретатор, полностью изолированный от других интерпретаторов, в том числе имеющий собственный GIL. Главное преимущество такой изоляции состоит в том, что этот интерпретатор может выполнять код Python, не блокируясь другими интерпретаторами и не блокируя их. Таким образом, один процесс Python может в полной мере использовать несколько ядер ЦП при выполнении кода Python. Изоляция также способствует применению иного подхода к параллелизму, отличного от простого использования потоков. (См. PEP 554 и PEP 684.)
Использование изолированного интерпретатора требует внимательного сохранения изоляции. В частности, нельзя совместно использовать объекты или изменяемое состояние, если нет гарантий потокобезопасности. Даже объекты, которые в остальном являются неизменяемыми (например, None, (1, 5)), обычно нельзя совместно использовать из-за счётчика ссылок. Один простой, но менее эффективный способ обойти это ограничение — использовать глобальную блокировку при любом обращении к некоторому состоянию (или объекту). Другой вариант: эффективно неизменяемые объекты (например, целые числа или строки) можно обезопасить, несмотря на их счётчики ссылок, сделав их бессмертными. Именно так и поступили со встроенными одиночными объектами, небольшими целыми числами и рядом других встроенных объектов.
Сохраняя изоляцию, вы получаете возможность полноценно использовать многопроцессорные вычисления без сложностей, связанных с отсутствием блокировки потоков. Нарушение изоляции повлечёт за собой все последствия отсутствия блокировки потоков, включая гонки данных и трудноотлаживаемые сбои.
Помимо этого, одна из главных сложностей при использовании нескольких изолированных интерпретаторов — безопасный (без нарушения изоляции) и эффективный обмен данными между ними. Среда выполнения и стандартная библиотека пока не предоставляют стандартного способа решения этой задачи. Будущий модуль стандартной библиотеки мог бы упростить сохранение изоляции и предоставить эффективные инструменты для обмена (и совместного использования) данными между интерпретаторами.
Добавлено в версии 3.12.
Ошибки и предостережения
Поскольку субинтерпретаторы (и главный интерпретатор) являются частью одного процесса, изоляция между ними не идеальна — например, низкоуровневые файловые операции, такие как os.close(), могут (случайно или преднамеренно) повлиять на открытые файлы других интерпретаторов. Из-за особенностей совместного использования расширений несколькими (суб-)интерпретаторами некоторые расширения могут работать некорректно; особенно вероятно это при использовании однофазной инициализации или (статических) глобальных переменных. Можно поместить объекты, созданные в одном субинтерпретаторе, в пространство имён другого (суб-)интерпретатора; по возможности этого следует избегать.
Следует проявлять особую осторожность и не допускать совместного использования пользовательских функций, методов, экземпляров или классов между субинтерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут повлиять на словарь загруженных модулей не того (суб-)интерпретатора. Не менее важно избегать совместного использования объектов, из которых доступны перечисленные выше объекты.
Также обратите внимание, что сочетание этой функциональности с API PyGILState_* требует осторожности, поскольку эти API предполагают взаимно однозначное соответствие между состояниями потоков Python и потоками на уровне ОС, а наличие субинтерпретаторов нарушает это предположение. Настоятельно рекомендуется не переключать субинтерпретаторы между парой соответствующих друг другу вызовов PyGILState_Ensure() и PyGILState_Release(). Кроме того, при использовании субинтерпретаторов, вероятно, будут работать некорректно расширения (например, ctypes), использующие эти API для вызова кода Python из потоков, созданных не средствами Python.
Асинхронные уведомления
Предусмотрен механизм для отправки асинхронных уведомлений главному потоку интерпретатора. Такие уведомления представляют собой указатель на функцию и аргумент-указатель void.
-
int Py_AddPendingCall(int (*func)(void*), void *arg) -
Часть стабильного ABI.
Планирует вызов функции из главного потока интерпретатора. В случае успеха возвращается
0, а функция func ставится в очередь для вызова в главном потоке. В случае ошибки возвращается-1без установки исключения.После успешной постановки в очередь функция func в конечном итоге будет вызвана из главного потока интерпретатора с аргументом arg. Вызов будет асинхронным относительно обычного выполнения кода Python, но должны соблюдаться оба следующих условия:
- на границе байткода;
- главный поток удерживает глобальную блокировку интерпретатора (поэтому func может использовать весь C API).
В случае успеха func должна вернуть
0, а в случае ошибки —-1и установить исключение. Выполнение func не будет прервано для рекурсивного вызова другого асинхронного уведомления, однако оно всё ещё может быть прервано переключением потоков, если глобальная блокировка интерпретатора освобождена.Для выполнения этой функции не требуется текущее состояние потока или глобальная блокировка интерпретатора.
Чтобы вызвать эту функцию в субинтерпретаторе, вызывающий код должен удерживать GIL. В противном случае функцию func можно запланировать для вызова не в том интерпретаторе.
Предупреждение
Это низкоуровневая функция, полезная лишь в особых случаях. Нет гарантии, что func будет вызвана как можно скорее. Если главный поток занят выполнением системного вызова, func не будет вызвана до его завершения. Эта функция обычно не подходит для вызова кода Python из произвольных потоков C. Вместо неё используйте API PyGILState.
Добавлено в версии 3.1.
Изменено в версии 3.9: Если эта функция вызвана в субинтерпретаторе, функция func теперь планируется для вызова из этого субинтерпретатора, а не из главного интерпретатора. Теперь у каждого субинтерпретатора есть собственный список запланированных вызовов.
Изменено в версии 3.12: Теперь эта функция всегда планирует выполнение func в главном интерпретаторе.
Профилирование и трассировка
Интерпретатор Python предоставляет некоторую низкоуровневую поддержку средств профилирования и трассировки выполнения. Они используются для профилирования, отладки и анализа покрытия кода.
Этот интерфейс C позволяет коду профилирования или трассировки избежать накладных расходов на вызов вызываемых объектов уровня Python, выполняя вместо этого прямой вызов функции C. Основные свойства этого механизма не изменились; интерфейс позволяет устанавливать функции трассировки для отдельных потоков, а базовые события, передаваемые функции трассировки, совпадают с теми, которые передавались функциям трассировки уровня Python в предыдущих версиях.
-
typedef int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) -
Тип функции трассировки, зарегистрированной с помощью
PyEval_SetProfile()иPyEval_SetTrace(). Первый параметр — объект, переданный функции регистрации как obj, frame — объект кадра, к которому относится событие, what — одна из константPyTrace_CALL,PyTrace_EXCEPTION,PyTrace_LINE,PyTrace_RETURN,PyTrace_C_CALL,PyTrace_C_EXCEPTION,PyTrace_C_RETURNилиPyTrace_OPCODE, а значение arg зависит от значения what:Значение what
Значение arg
Всегда
Py_None.Информация об исключении, возвращаемая функцией
sys.exc_info().Всегда
Py_None.Значение, возвращаемое вызывающему коду, или
NULL, если возврат вызван исключением.Вызываемый объект функции.
Вызываемый объект функции.
Вызываемый объект функции.
Всегда
Py_None.
-
int PyTrace_CALL -
Значение параметра what функции
Py_tracefunc, когда сообщается о новом вызове функции или метода либо о новом входе в генератор. Обратите внимание, что создание итератора для функции-генератора не отслеживается, поскольку в соответствующем кадре не происходит передачи управления байт-коду Python.
-
int PyTrace_EXCEPTION -
Значение параметра what функции
Py_tracefunc, когда возникает исключение. Функция обратного вызова вызывается с этим значением what после обработки любого байт-кода, после которого в выполняемом кадре устанавливается исключение. В результате, по мере того как распространение исключения приводит к разматыванию стека Python, функция обратного вызова вызывается при возврате в каждый кадр по мере распространения исключения. Эти события получают только функции трассировки; профилировщику они не нужны.
-
int PyTrace_LINE -
Значение параметра what, передаваемое функции
Py_tracefunc(но не функции профилирования), когда сообщается о событии номера строки. Для кадра это событие можно отключить, задав значение 0 атрибутуf_trace_linesэтого кадра.
-
int PyTrace_RETURN -
Значение параметра what функций
Py_tracefunc, когда вызов собирается завершиться возвратом.
-
int PyTrace_C_CALL -
Значение параметра what функций
Py_tracefunc, когда собираются вызвать функцию C.
-
int PyTrace_C_EXCEPTION -
Значение параметра what функций
Py_tracefunc, когда функция C вызвала исключение.
-
int PyTrace_C_RETURN -
Значение параметра what функций
Py_tracefunc, когда функция C завершила работу.
-
int PyTrace_OPCODE -
Значение параметра what функций
Py_tracefunc(но не функций профилирования), когда собирается выполниться новая инструкция байт-кода. По умолчанию это событие не генерируется: для его включения необходимо явно задать значение 1 атрибутуf_trace_opcodesкадра.
-
void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) -
Устанавливает функцию профилирования func. Параметр obj передаётся функции как первый параметр и может быть любым объектом Python или
NULL. Если функции профилирования необходимо сохранять состояние, использование разных значений obj для каждого потока предоставляет удобное и потокобезопасное место для его хранения. Функция профилирования вызывается для всех отслеживаемых событий, кромеPyTrace_LINE,PyTrace_OPCODEиPyTrace_EXCEPTION.См. также функцию
sys.setprofile().Вызывающий код должен удерживать GIL.
-
void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj) -
Подобно
PyEval_SetProfile(), но устанавливает функцию профилирования во всех работающих потоках текущего интерпретатора, а не только в текущем потоке.Вызывающий код должен удерживать GIL.
Как и
PyEval_SetProfile(), эта функция игнорирует исключения, возникающие при установке функций профилирования во всех потоках.
Добавлено в версии 3.12.
-
void PyEval_SetTrace(Py_tracefunc func, PyObject *obj) -
Устанавливает функцию трассировки func. Эта функция похожа на
PyEval_SetProfile(), но функция трассировки получает события номеров строк и события для отдельных инструкций байт-кода, а также не получает события, связанные с вызовом объектов функций C. Функция трассировки, зарегистрированная с помощьюPyEval_SetTrace(), не будет получатьPyTrace_C_CALL,PyTrace_C_EXCEPTIONилиPyTrace_C_RETURNв качестве значения параметра what.См. также функцию
sys.settrace().Вызывающий код должен удерживать GIL.
-
void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj) -
Подобно
PyEval_SetTrace(), но устанавливает функцию трассировки во всех работающих потоках текущего интерпретатора, а не только в текущем потоке.Вызывающий код должен удерживать GIL.
Как и
PyEval_SetTrace(), эта функция игнорирует исключения, возникающие при установке функций трассировки во всех потоках.
Добавлено в версии 3.12.
Трассировка ссылок
Добавлено в версии 3.13.
-
typedef int (*PyRefTracer)(PyObject*, int event, void *data) -
Тип функции трассировки, зарегистрированной с помощью
PyRefTracer_SetTracer(). Первый параметр — только что созданный объект Python (если для event задано значениеPyRefTracer_CREATE) или объект, который собираются уничтожить (если для event задано значениеPyRefTracer_DESTROY). Аргумент data — это непрозрачный указатель, переданный при вызовеPyRefTracer_SetTracer().
Добавлено в версии 3.13.
-
int PyRefTracer_CREATE -
Значение параметра event функций
PyRefTracer, когда создан объект Python.
-
int PyRefTracer_DESTROY -
Значение параметра event функций
PyRefTracer, когда объект Python уничтожен.
-
int PyRefTracer_SetTracer(PyRefTracer tracer, void *data) -
Регистрирует функцию трассировки ссылок. Функция вызывается при создании нового объекта Python или перед уничтожением объекта. Если указан data, он должен быть непрозрачным указателем, который будет передан при вызове функции трассировки. При успешном выполнении возвращает
0. В случае ошибки устанавливает исключение и возвращает-1.Обратите внимание: функции трассировки не должны создавать объекты Python, иначе вызов станет реентерабельным. Трассировщик также не должен сбрасывать существующее исключение или устанавливать исключение. При каждом вызове функции трассировки будет удерживаться GIL.
При вызове этой функции необходимо удерживать GIL.
Добавлено в версии 3.13.
-
PyRefTracer PyRefTracer_GetTracer(void **data) -
Возвращает зарегистрированную функцию трассировки ссылок и значение непрозрачного указателя данных, зарегистрированного при вызове
PyRefTracer_SetTracer(). Если трассировщик не зарегистрирован, эта функция возвращает NULL и устанавливает для указателя data значение NULL.При вызове этой функции необходимо удерживать GIL.
Добавлено в версии 3.13.
Расширенная поддержка отладчиков
Эти функции предназначены только для использования средствами расширенной отладки.
-
PyInterpreterState *PyInterpreterState_Head() -
Возвращает объект состояния интерпретатора, находящийся в начале списка всех таких объектов.
-
PyInterpreterState *PyInterpreterState_Main() -
Возвращает объект состояния главного интерпретатора.
-
PyInterpreterState *PyInterpreterState_Next(PyInterpreterState *interp) -
Возвращает следующий за interp объект состояния интерпретатора из списка всех таких объектов.
-
PyThreadState *PyInterpreterState_ThreadHead(PyInterpreterState *interp) -
Возвращает указатель на первый объект
PyThreadStateв списке потоков, связанных с интерпретатором interp.
-
PyThreadState *PyThreadState_Next(PyThreadState *tstate) -
Возвращает следующий за tstate объект состояния потока из списка всех таких объектов, принадлежащих одному и тому же объекту
PyInterpreterState.
Поддержка локального хранилища потока
Интерпретатор Python предоставляет низкоуровневую поддержку локального хранилища потока (TLS), которая оборачивает базовую реализацию TLS платформы для поддержки API локального хранилища потоков уровня Python (threading.local). API уровня C в CPython похожи на API, предлагаемые pthreads и Windows: используйте ключ потока и функции, чтобы связать значение void* с каждым потоком.
При вызове этих функций удерживать GIL не требуется; они используют собственные блокировки.
Обратите внимание, что Python.h не содержит объявлений API TLS; для использования локального хранилища потока необходимо включить pythread.h.
Примечание
Ни одна из этих функций API не управляет памятью, выделенной для значений void*. Вы должны выделять и освобождать её самостоятельно. Если значения void* окажутся объектами PyObject*, эти функции также не будут выполнять для них операции со счётчиком ссылок.
API хранилища, специфичного для потока (TSS)
API TSS введён, чтобы заменить использование существующего API TLS в интерпретаторе CPython. В этом API для представления ключей потоков используется новый тип Py_tss_t вместо int.
Добавлено в версии 3.7.
См. также
«Новый C API для локального хранилища потоков в CPython» (PEP 539)
-
type Py_tss_t -
Эта структура данных представляет состояние ключа потока; его определение может зависеть от базовой реализации TLS. Структура содержит внутреннее поле, представляющее состояние инициализации ключа. В этой структуре нет общедоступных членов.
Если Py_LIMITED_API не определён, допускается статическое выделение памяти для этого типа с помощью
Py_tss_NEEDS_INIT.
-
Py_tss_NEEDS_INIT -
Этот макрос раскрывается в инициализатор для переменных типа
Py_tss_t. Обратите внимание, что этот макрос не будет определён при использовании Py_LIMITED_API.
Динамическое выделение памяти
Динамическое выделение памяти для Py_tss_t требуется в модулях расширений, собранных с Py_LIMITED_API, поскольку статическое выделение памяти для этого типа невозможно: его реализация непрозрачна во время сборки.
-
Py_tss_t *PyThread_tss_alloc() -
Часть стабильного ABI начиная с версии 3.7.
Возвращает значение с тем же состоянием, что и значение, инициализированное с помощью
Py_tss_NEEDS_INIT, илиNULLв случае сбоя динамического выделения памяти.
-
void PyThread_tss_free(Py_tss_t *key) -
Часть стабильного ABI начиная с версии 3.7.
Освобождает заданный key, выделенный с помощью
PyThread_tss_alloc(), предварительно вызвавPyThread_tss_delete(), чтобы гарантировать отмену привязки всех связанных локальных данных потоков. Если аргумент key равенNULL, функция ничего не делает.Примечание
Освобождённый ключ становится висячим указателем. Необходимо сбросить ключ в
NULL.
Методы
Параметр key этих функций не должен быть равен NULL. Кроме того, поведение PyThread_tss_set() и PyThread_tss_get() не определено, если заданный Py_tss_t не был инициализирован с помощью PyThread_tss_create().
-
int PyThread_tss_is_created(Py_tss_t *key) -
Часть стабильного ABI начиная с версии 3.7.
Возвращает ненулевое значение, если заданный
Py_tss_tбыл инициализирован с помощьюPyThread_tss_create().
-
int PyThread_tss_create(Py_tss_t *key) -
Часть стабильного ABI начиная с версии 3.7.
Возвращает нулевое значение при успешной инициализации ключа TSS. Поведение не определено, если значение, на которое указывает аргумент key, не было инициализировано с помощью
Py_tss_NEEDS_INIT. Эту функцию можно вызывать несколько раз для одного и того же ключа — вызов для уже инициализированного ключа ничего не делает и сразу возвращает успешный результат.
-
void PyThread_tss_delete(Py_tss_t *key) -
Часть стабильного ABI начиная с версии 3.7.
Уничтожает ключ TSS, удаляя связанные с ним значения во всех потоках, и переводит состояние инициализации ключа в неинициализированное. Уничтоженный ключ можно повторно инициализировать с помощью
PyThread_tss_create(). Эту функцию можно вызывать несколько раз для одного и того же ключа — вызов для уже уничтоженного ключа ничего не делает.
-
int PyThread_tss_set(Py_tss_t *key, void *value) -
Часть стабильного ABI начиная с версии 3.7.
Возвращает нулевое значение, указывающее на успешную привязку значения void* к ключу TSS в текущем потоке. Для каждого потока существует отдельное соответствие ключа значению void*.
-
void *PyThread_tss_get(Py_tss_t *key) -
Часть стабильного ABI начиная с версии 3.7.
Возвращает значение void*, связанное с ключом TSS в текущем потоке. Если в текущем потоке с ключом не связано никакое значение, возвращается
NULL.
API локального хранилища потока (TLS)
Устарело начиная с версии 3.7: Этот API заменён API хранилища, специфичного для потока (TSS).
Примечание
Эта версия API не поддерживает платформы, где собственный TLS-ключ определён таким образом, что его нельзя безопасно привести к типу int. На таких платформах PyThread_create_key() немедленно вернёт код ошибки, а остальные функции TLS не будут выполнять никаких действий.
Из-за упомянутой выше проблемы совместимости эту версию API не следует использовать в новом коде.
-
int PyThread_create_key() - Часть стабильного ABI.
-
void PyThread_delete_key(int key) - Часть стабильного ABI.
-
int PyThread_set_key_value(int key, void *value) - Часть стабильного ABI.
-
void *PyThread_get_key_value(int key) - Часть стабильного ABI.
-
void PyThread_delete_key_value(int key) - Часть стабильного ABI.
-
void PyThread_ReInitTLS() - Часть стабильного ABI.
Примитивы синхронизации
C-API предоставляет базовую блокировку взаимного исключения.
-
type PyMutex -
Блокировка взаимного исключения.
PyMutexследует инициализировать нулём, чтобы представить состояние разблокировки. Например:PyMutex mutex = {0};Экземпляры
PyMutexне следует копировать или перемещать. Значимы как содержимое, так и адресPyMutex, поэтому оно должно оставаться в фиксированном, доступном для записи месте в памяти.Примечание
В настоящее время
PyMutexзанимает один байт, однако размер следует считать нестабильным. В будущих выпусках Python размер может измениться без периода устаревания.Добавлено в версии 3.13.
-
void PyMutex_Lock(PyMutex *m) -
Блокирует мьютекс m. Если другой поток уже заблокировал его, вызывающий поток будет ожидать, пока мьютекс не будет разблокирован. Во время ожидания поток временно освобождает GIL, если он захвачен.
Добавлено в версии 3.13.
-
void PyMutex_Unlock(PyMutex *m) -
Разблокирует мьютекс m. Мьютекс должен быть заблокирован — в противном случае функция вызовет фатальную ошибку.
Добавлено в версии 3.13.
API критических секций Python
API критических секций предоставляет уровень предотвращения взаимоблокировок поверх блокировок отдельных объектов для свободнопоточного CPython. Этот API предназначен для замены зависимости от глобальной блокировки интерпретатора и ничего не делает в версиях Python с глобальной блокировкой интерпретатора.
Критические секции предназначены для пользовательских типов, реализованных в расширениях C-API. Как правило, их не следует использовать со встроенными типами, такими как list и dict, поскольку их открытые C-API уже используют критические секции внутри. Примечательное исключение — PyDict_Next(), для которого критическую секцию необходимо захватить извне.
Критические секции предотвращают взаимоблокировки, неявно приостанавливая активные критические секции, поэтому они не обеспечивают эксклюзивный доступ, как традиционные блокировки, например PyMutex. При начале критической секции захватывается блокировка соответствующего объекта. Если код, выполняемый внутри критической секции, вызывает функции C-API, критическая секция может быть приостановлена, что приведёт к освобождению блокировки объекта, и другие потоки смогут захватить блокировку того же объекта.
Функции и структуры, используемые макросами, доступны в случаях, когда макросы C недоступны. Их следует использовать только так, как указано в раскрытии соответствующих макросов. Обратите внимание, что размеры и содержимое структур могут измениться в будущих версиях Python.
Примечание
Операции, которым необходимо одновременно заблокировать два объекта, должны использовать Py_BEGIN_CRITICAL_SECTION2. Нельзя использовать вложенные критические секции, чтобы одновременно заблокировать более одного объекта, поскольку внутренняя критическая секция может приостановить внешние критические секции. Этот API не позволяет одновременно блокировать более двух объектов.
Пример использования:
static PyObject *
set_field(MyObject *self, PyObject *value)
{
Py_BEGIN_CRITICAL_SECTION(self);
Py_SETREF(self->field, Py_XNewRef(value));
Py_END_CRITICAL_SECTION();
Py_RETURN_NONE;
}
В приведённом выше примере Py_SETREF вызывает Py_DECREF, которая может вызвать произвольный код через функцию деаллокации объекта. API критических секций предотвращает потенциальные взаимоблокировки из-за повторного входа и порядка захвата блокировок, позволяя среде выполнения временно приостановить критическую секцию, если код, вызванный финализатором, блокируется и вызывает PyEval_SaveThread().
-
Py_BEGIN_CRITICAL_SECTION(op) -
Захватывает блокировку объекта op и начинает критическую секцию.
В сборке без GIL этот макрос раскрывается в:
{ PyCriticalSection _py_cs; PyCriticalSection_Begin(&_py_cs, (PyObject*)(op))В сборке по умолчанию этот макрос раскрывается в
{.Добавлено в версии 3.13.
-
Py_END_CRITICAL_SECTION() -
Завершает критическую секцию и освобождает блокировку объекта.
В сборке без GIL этот макрос раскрывается в:
PyCriticalSection_End(&_py_cs); }
В сборке по умолчанию этот макрос раскрывается в
}.Добавлено в версии 3.13.
-
Py_BEGIN_CRITICAL_SECTION2(a, b) -
Захватывает блокировки объектов a и b и начинает критическую секцию. Блокировки захватываются в согласованном порядке (сначала по наименьшему адресу), чтобы избежать взаимоблокировок из-за порядка захвата блокировок.
В сборке без GIL этот макрос раскрывается в:
{ PyCriticalSection2 _py_cs2; PyCriticalSection2_Begin(&_py_cs2, (PyObject*)(a), (PyObject*)(b))В сборке по умолчанию этот макрос раскрывается в
{.Добавлено в версии 3.13.
-
Py_END_CRITICAL_SECTION2() -
Завершает критическую секцию и освобождает блокировки объектов.
В сборке без GIL этот макрос раскрывается в:
PyCriticalSection2_End(&_py_cs2); }
В сборке по умолчанию этот макрос раскрывается в
}.Добавлено в версии 3.13.
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/c-api/init.html