Инициализация, финализация и потоки
См. также Конфигурация инициализации Python.
До инициализации Python
В приложении, встраивающем Python, функцию Py_Initialize() необходимо вызвать до использования любых других функций API Python/C; за исключением нескольких функций и глобальных переменных конфигурации.
До инициализации Python можно безопасно вызывать следующие функции:
-
Функции конфигурации:
-
Информационные функции:
-
Утилиты:
-
Аллокаторы памяти:
Примечание
Следующие функции не следует вызывать до Py_Initialize(): Py_EncodeLocale(), Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), Py_GetProgramFullPath(), Py_GetPythonHome(), Py_GetProgramName() и PyEval_InitThreads().
Глобальные переменные конфигурации
В 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.
-
int Py_DebugFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.parser_debug; см. Конфигурация инициализации Python.Включить отладочный вывод анализатора (только для опытных пользователей; зависит от параметров компиляции).
Устанавливается параметром
-dи переменной окруженияPYTHONDEBUG.Устарело начиная с версии 3.12.
-
int Py_DontWriteBytecodeFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.write_bytecode; см. Конфигурация инициализации Python.Если значение ненулевое, Python не будет пытаться записывать файлы
.pycпри импорте исходных модулей.Устанавливается параметром
-Bи переменной окруженияPYTHONDONTWRITEBYTECODE.Устарело начиная с версии 3.12.
-
int Py_FrozenFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.pathconfig_warnings; см. Конфигурация инициализации Python.Подавлять сообщения об ошибках при вычислении пути поиска модулей в
Py_GetPath().Закрытый флаг, используемый программами
_freeze_moduleиfrozenmain.Устарело начиная с версии 3.12.
-
int Py_HashRandomizationFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.hash_seedиPyConfig.use_hash_seed; см. Конфигурация инициализации Python.Устанавливается в
1, если переменная окруженияPYTHONHASHSEEDзадана непустой строкой.Если значение флага ненулевое, считывать переменную окружения
PYTHONHASHSEEDдля инициализации секретного начального значения хэша.Устарело начиная с версии 3.12.
-
int Py_IgnoreEnvironmentFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.use_environment; см. Конфигурация инициализации Python.Игнорировать все переменные окружения
PYTHON*, напримерPYTHONPATHиPYTHONHOME, которые могут быть заданы.Устанавливается параметрами
-Eи-I.Устарело начиная с версии 3.12.
-
int Py_InspectFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.inspect; см. Конфигурация инициализации Python.Если скрипт передан в качестве первого аргумента или используется параметр
-c, перейти в интерактивный режим после выполнения скрипта или команды, даже еслиsys.stdinне является терминалом.Устанавливается параметром
-iи переменной окруженияPYTHONINSPECT.Устарело начиная с версии 3.12.
-
int Py_InteractiveFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.interactive; см. Конфигурация инициализации Python.Устанавливается параметром
-i.Устарело начиная с версии 3.12.
-
int Py_IsolatedFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.isolated; см. Конфигурация инициализации Python.Запускать Python в изолированном режиме. В изолированном режиме
sys.pathне содержит ни каталог скрипта, ни каталог пользовательских site-packages.Устанавливается параметром
-I.Добавлено в версии 3.4.
Устарело начиная с версии 3.12.
-
int Py_LegacyWindowsFSEncodingFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyPreConfig.legacy_windows_fs_encoding; см. Конфигурация инициализации Python.Если значение флага ненулевое, для кодировки файловой системы и обработчика ошибок используется кодировка
mbcsс обработчиком ошибокreplaceвместо кодировки UTF-8 с обработчиком ошибокsurrogatepass.Устанавливается в
1, если переменная окруженияPYTHONLEGACYWINDOWSFSENCODINGзадана непустой строкой.Подробнее см. PEP 529.
Доступность: Windows.
Устарело начиная с версии 3.12.
-
int Py_LegacyWindowsStdioFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.legacy_windows_stdio; см. Конфигурация инициализации Python.Если значение флага ненулевое, для стандартных потоков
sysиспользуетсяio.FileIOвместоio._WindowsConsoleIO.Устанавливается в
1, если переменная окруженияPYTHONLEGACYWINDOWSSTDIOзадана непустой строкой.Подробнее см. PEP 528.
Доступность: Windows.
Устарело начиная с версии 3.12.
-
int Py_NoSiteFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.site_import; см. Конфигурация инициализации Python.Отключить импорт модуля
siteи зависящие от сайта измененияsys.path, которые он выполняет. Эти изменения также отключаются, если модульsiteявно импортирован позднее (если необходимо запустить их выполнение, вызовитеsite.main()).Устанавливается параметром
-S.Устарело начиная с версии 3.12.
-
int Py_NoUserSiteDirectory -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.user_site_directory; см. Конфигурация инициализации Python.Не добавлять
user site-packages directoryвsys.path.Устанавливается параметрами
-sи-I, а также переменной окруженияPYTHONNOUSERSITE.Устарело начиная с версии 3.12.
-
int Py_OptimizeFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.optimization_level; см. Конфигурация инициализации Python.Устанавливается параметром
-Oи переменной окруженияPYTHONOPTIMIZE.Устарело начиная с версии 3.12.
-
int Py_QuietFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.quiet; см. Конфигурация инициализации Python.Не отображать сообщения об авторских правах и версии даже в интерактивном режиме.
Устанавливается параметром
-q.Добавлено в версии 3.2.
Устарело начиная с версии 3.12.
-
int Py_UnbufferedStdioFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.buffered_stdio; см. Конфигурация инициализации Python.Принудительно отключить буферизацию потоков stdout и stderr.
Устанавливается параметром
-uи переменной окруженияPYTHONUNBUFFERED.Устарело начиная с версии 3.12.
-
int Py_VerboseFlag -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.verbose; см. Конфигурация инициализации Python.Выводить сообщение при каждой инициализации модуля с указанием места его загрузки (имя файла или встроенный модуль). Если значение больше или равно
2, выводить сообщение для каждого файла, проверяемого при поиске модуля. Также выводить сведения об очистке модулей при завершении.Устанавливается параметром
-vи переменной окруженияPYTHONVERBOSE.Устарело начиная с версии 3.12.
Инициализация и завершение работы интерпретатора
-
void Py_Initialize() -
Часть Стабильного ABI.
Инициализирует интерпретатор Python. В приложении, встраивающем Python, эту функцию следует вызвать до использования любых других функций Python/C API; исключения описаны в разделе До инициализации Python.
Инициализирует таблицу загруженных модулей (
sys.modules) и создаёт основные модулиbuiltins,__main__иsys. Кроме того, инициализирует путь поиска модулей (sys.path). Не задаётsys.argv; для этого используйтеPySys_SetArgvEx(). Повторный вызов этой функции ничего не делает (если перед этим не была вызванаPy_FinalizeEx()). Возвращаемого значения нет; если инициализация завершается с ошибкой, это приводит к аварийному завершению.Для настройки конфигурации инициализации Python используйте функцию
Py_InitializeFromConfig().Примечание
В Windows изменяет режим консоли с
O_TEXTнаO_BINARY, что также влияет на использование консоли средствами среды выполнения C вне Python.
-
void Py_InitializeEx(int initsigs) -
Часть Стабильного ABI.
Эта функция работает так же, как
Py_Initialize(), если initsigs равно1. Если initsigs равно0, функция пропускает регистрацию обработчиков сигналов при инициализации; это может быть полезно при встраивании Python.Для настройки конфигурации инициализации Python используйте функцию
Py_InitializeFromConfig().
-
int Py_IsInitialized() -
Часть Стабильного ABI.
Возвращает true (ненулевое значение), если интерпретатор Python инициализирован, и false (нулевое значение) в противном случае. После вызова
Py_FinalizeEx()функция возвращает false, пока снова не будет вызванаPy_Initialize().
-
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 без перезапуска самого приложения. Приложению, загрузившему интерпретатор Python из динамически загружаемой библиотеки (или DLL), может потребоваться освободить всю память, выделенную Python, прежде чем выгрузить DLL. При поиске утечек памяти в приложении разработчик может захотеть освободить всю память, выделенную Python, до завершения приложения.
Ошибки и предостережения: Уничтожение модулей и объектов в модулях выполняется в случайном порядке; это может привести к сбоям деструкторов (методов
__del__()), если они зависят от других объектов (в том числе функций) или модулей. Динамически загруженные Python модули расширений не выгружаются. Небольшие объёмы памяти, выделенной интерпретатором Python, могут остаться неосвобождёнными (если вы обнаружили утечку, сообщите о ней). Память, занятая циклическими ссылками между объектами, не освобождается. Некоторая память, выделенная модулями расширений, может остаться неосвобождённой. Некоторые расширения могут работать некорректно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение вызываетPy_Initialize()иPy_FinalizeEx()несколько раз.Вызывает событие аудита
cpython._PySys_ClearAuditHooksбез аргументов.Добавлено в версии 3.6.
-
void Py_Finalize() -
Часть Стабильного ABI.
Это обратно совместимая версия
Py_FinalizeEx(), которая игнорирует возвращаемое значение.
Параметры уровня процесса
-
int Py_SetStandardStreamEncoding(const char *encoding, const char *errors) -
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.stdio_encodingиPyConfig.stdio_errors; см. Конфигурация инициализации Python.Эту функцию следует вызывать до
Py_Initialize(), если она вообще вызывается. Она задаёт кодировку и обработчик ошибок для стандартного ввода-вывода; их значения соответствуют значениям вstr.encode().Она переопределяет значения
PYTHONIOENCODINGи позволяет встраиваемому коду управлять кодировкой ввода-вывода, когда переменная окружения не работает.encoding и/или errors могут иметь значение
NULL, чтобы использоватьPYTHONIOENCODINGи/или значения по умолчанию (в зависимости от других настроек).Обратите внимание, что
sys.stderrвсегда использует обработчик ошибок «backslashreplace» независимо от этой (или любой другой) настройки.Если вызывается
Py_FinalizeEx(), для применения настройки к последующим вызовамPy_Initialize()эту функцию потребуется вызвать повторно.В случае успеха возвращает
0, при ошибке (например, при вызове после инициализации интерпретатора) — ненулевое значение.Добавлено в версии 3.4.
Устарело с версии 3.11.
-
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.
Возвращает имя программы, заданное с помощью
Py_SetProgramName(), или значение по умолчанию. Возвращённая строка находится в статической памяти; вызывающий код не должен изменять её.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().
-
wchar_t *Py_GetPrefix() -
Часть стабильного ABI.
Возвращает префикс для установленных платформонезависимых файлов. Он вычисляется по ряду сложных правил на основе имени программы, заданного с помощью
Py_SetProgramName(), и некоторых переменных окружения; например, если имя программы —'/usr/local/bin/python', префикс —'/usr/local'. Возвращённая строка находится в статической памяти; вызывающий код не должен изменять её. Она соответствует переменной prefix в корневомMakefileи аргументу--prefixсценария configure на этапе сборки. Это значение доступно коду Python какsys.prefix. Оно имеет смысл только в Unix. См. также следующую функцию.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().
-
wchar_t *Py_GetExecPrefix() -
Часть стабильного ABI.
Возвращает exec-префикс для установленных платформозависимых файлов. Он вычисляется по ряду сложных правил на основе имени программы, заданного с помощью
Py_SetProgramName(), и некоторых переменных окружения; например, если имя программы —'/usr/local/bin/python', exec-префикс —'/usr/local'. Возвращённая строка находится в статической памяти; вызывающий код не должен изменять её. Она соответствует переменной exec_prefix в корневомMakefileи аргументу--exec-prefixсценария configure на этапе сборки. Это значение доступно коду Python какsys.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().
-
wchar_t *Py_GetProgramFullPath() -
Часть стабильного ABI.
Возвращает полный путь к исполняемому файлу Python; он вычисляется как побочный эффект определения пути поиска модулей по умолчанию на основе имени программы (заданного выше с помощью
Py_SetProgramName()). Возвращённая строка находится в статической памяти; вызывающий код не должен изменять её. Это значение доступно коду Python какsys.executable.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().
-
wchar_t *Py_GetPath() -
Часть стабильного ABI.
Возвращает путь поиска модулей по умолчанию; он вычисляется на основе имени программы (заданного выше с помощью
Py_SetProgramName()) и некоторых переменных окружения. Возвращённая строка состоит из имён каталогов, разделённых символом-разделителем, зависящим от платформы. В Unix и macOS это':', в Windows —';'. Возвращённая строка находится в статической памяти; вызывающий код не должен изменять её. При запуске интерпретатора списокsys.pathинициализируется этим значением; позднее его можно (и обычно так и делают) изменить, чтобы задать путь поиска модулей.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().
-
void Py_SetPath(const wchar_t*) -
Часть стабильного ABI с версии 3.7.
Этот API сохранён для обратной совместимости: вместо него следует задавать
PyConfig.module_search_pathsиPyConfig.module_search_paths_set; см. Конфигурация инициализации Python.Задаёт путь поиска модулей по умолчанию. Если эту функцию вызвать до
Py_Initialize(), тоPy_GetPath()не будет вычислять путь поиска по умолчанию, а использует заданный путь. Это полезно, если Python встраивается в приложение, которому точно известно расположение всех модулей. Компоненты пути следует разделять символом-разделителем, зависящим от платформы: в Unix и macOS это':', в Windows —';'.Кроме того, это приводит к тому, что для
sys.executableзадаётся полный путь к программе (см.Py_GetProgramFullPath()), аsys.prefixиsys.exec_prefixстановятся пустыми. При необходимости вызывающий код должен изменить эти значения после вызоваPy_Initialize().Используйте
Py_DecodeLocale(), чтобы декодировать строку байтов и получить строку wchar_*.Аргумент path копируется внутри функции, поэтому вызывающий код может освободить его после завершения вызова.
Изменено в версии 3.8: Теперь для
sys.executableиспользуется полный путь к программе, а не её имя.Устарело с версии 3.11.
-
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()со значением updatepath1, если только интерпретатор 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» по умолчанию, то есть значение, заданное предыдущим вызовом
Py_SetPythonHome(), или значение переменной окруженияPYTHONHOME, если она задана.Эту функцию не следует вызывать до
Py_Initialize(), иначе она возвращаетNULL.Изменено в версии 3.10: Теперь возвращает
NULL, если вызвана доPy_Initialize().
Состояние потока и глобальная блокировка интерпретатора
Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python существует глобальная блокировка, называемая глобальной блокировкой интерпретатора или GIL, которую текущий поток должен удерживать, прежде чем безопасно обращаться к объектам Python. Без этой блокировки даже самые простые операции могут вызвать проблемы в многопоточной программе: например, если два потока одновременно увеличивают счётчик ссылок одного и того же объекта, счётчик ссылок может увеличиться только на единицу, а не на две.
Поэтому действует правило: только поток, получивший GIL, может работать с объектами Python или вызывать функции Python/C API. Чтобы имитировать параллельное выполнение, интерпретатор регулярно пытается переключать потоки (см. 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.
Поскольку остаётся только «текущий» поток, блокировки, удерживаемые другими потоками, никогда не будут освобождены. Python решает эту проблему для os.fork(): перед 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().
Высокоуровневый API
Ниже перечислены наиболее часто используемые типы и функции при написании кода расширений на C или встраивании интерпретатора Python:
-
type PyInterpreterState -
Часть ограниченного API (в виде непрозрачной структуры).
Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, используют общие средства управления модулями и некоторые другие внутренние элементы. Эта структура не содержит общедоступных полей.
Потоки, принадлежащие разным интерпретаторам, изначально не имеют ничего общего, за исключением состояния процесса, например доступной памяти, открытых файловых дескрипторов и прочего. Глобальная блокировка интерпретатора также общая для всех потоков, независимо от того, к какому интерпретатору они принадлежат.
-
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.
-
int PyEval_ThreadsInitialized() -
Часть стабильного ABI.
Возвращает ненулевое значение, если была вызвана функция
PyEval_InitThreads(). Эту функцию можно вызывать, не удерживая GIL, поэтому её можно использовать, чтобы избегать вызовов API блокировок при однопоточном выполнении.Изменено в версии 3.7: Теперь GIL инициализируется функцией
Py_Initialize().Устарела с версии 3.9.
-
PyThreadState *PyEval_SaveThread() -
Часть стабильного ABI.
Освобождает глобальную блокировку интерпретатора (если она была создана) и сбрасывает состояние потока до
NULL, возвращая предыдущее состояние потока (которое не равноNULL). Если блокировка была создана, текущий поток должен был её получить.
-
void PyEval_RestoreThread(PyThreadState *tstate) -
Часть стабильного ABI.
Получает глобальную блокировку интерпретатора (если она была создана) и устанавливает состояние потока в tstate, которое не должно быть равно
NULL. Если блокировка была создана, текущий поток не должен был её получить, иначе возникнет взаимная блокировка.Примечание
Вызов этой функции из потока во время завершения работы среды выполнения приведёт к завершению потока, даже если он был создан не Python. Перед вызовом этой функции можно использовать
_Py_IsFinalizing()илиsys.is_finalizing(), чтобы проверить, завершается ли работа интерпретатора, и избежать нежелательного завершения потока.
-
PyThreadState *PyThreadState_Get() -
Часть стабильного ABI.
Возвращает текущее состояние потока. Глобальная блокировка интерпретатора должна быть получена. Если текущее состояние потока равно
NULL, возникает фатальная ошибка (поэтому вызывающей стороне не нужно проверять его наNULL).
-
PyThreadState *PyThreadState_Swap(PyThreadState *tstate) -
Часть стабильного ABI.
Меняет текущее состояние потока на состояние, переданное аргументом 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. Перед вызовом этой функции можно использовать
_Py_IsFinalizing()илиsys.is_finalizing(), чтобы проверить, завершается ли работа интерпретатора, и избежать нежелательного завершения потока.
-
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().
-
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.
-
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, которое не должно быть
NULL. Блокировка должна быть создана ранее. Если этот поток уже удерживает блокировку, возникнет взаимная блокировка.Примечание
Вызов этой функции из потока во время завершения работы среды выполнения приведёт к завершению потока, даже если он был создан не Python. Чтобы избежать нежелательного завершения, перед вызовом этой функции можно проверить, выполняется ли завершение интерпретатора, с помощью
_Py_IsFinalizing()илиsys.is_finalizing().Изменено в версии 3.8: Поведение приведено в соответствие с
PyEval_RestoreThread(),Py_END_ALLOW_THREADS()иPyGILState_Ensure(): текущий поток завершается, если функция вызвана во время завершения работы интерпретатора.PyEval_RestoreThread()— это высокоуровневая функция, которая всегда доступна (даже если потоки не были инициализированы).
-
void PyEval_ReleaseThread(PyThreadState *tstate) -
Часть стабильного ABI.
Сбрасывает текущее состояние потока до
NULLи освобождает блокировку глобального интерпретатора. Блокировка должна быть создана ранее и удерживаться текущим потоком. Аргумент tstate, который не должен бытьNULL, используется только для проверки того, что он представляет текущее состояние потока. Если это не так, сообщается о фатальной ошибке.PyEval_SaveThread()— это высокоуровневая функция, которая всегда доступна (даже если потоки не были инициализированы).
-
void PyEval_AcquireLock() -
Часть стабильного ABI.
Захватывает блокировку глобального интерпретатора. Блокировка должна быть создана ранее. Если этот поток уже удерживает блокировку, возникнет взаимная блокировка.
Устарело с версии 3.2: Эта функция не обновляет текущее состояние потока. Вместо неё используйте
PyEval_RestoreThread()илиPyEval_AcquireThread().Примечание
Вызов этой функции из потока во время завершения работы среды выполнения приведёт к завершению потока, даже если он был создан не Python. Чтобы избежать нежелательного завершения, перед вызовом этой функции можно проверить, выполняется ли завершение интерпретатора, с помощью
_Py_IsFinalizing()илиsys.is_finalizing().Изменено в версии 3.8: Поведение приведено в соответствие с
PyEval_RestoreThread(),Py_END_ALLOW_THREADS()иPyGILState_Ensure(): текущий поток завершается, если функция вызвана во время завершения работы интерпретатора.
-
void PyEval_ReleaseLock() -
Часть стабильного ABI.
Освобождает блокировку глобального интерпретатора. Блокировка должна быть создана ранее.
Устарело с версии 3.2: Эта функция не обновляет текущее состояние потока. Вместо неё используйте
PyEval_SaveThread()илиPyEval_ReleaseThread().
Поддержка субинтерпретаторов
В большинстве случаев вы будете встраивать только один интерпретатор 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 -
Это значение определяет работу ГИЛ субинтерпретатора. Оно может принимать одно из следующих значений:
-
PyInterpreterConfig_DEFAULT_GIL -
Использовать значение по умолчанию (
PyInterpreterConfig_SHARED_GIL).
-
PyInterpreterConfig_SHARED_GIL -
Использовать ГИЛ основного интерпретатора (совместно с ним).
-
PyInterpreterConfig_OWN_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, перед вызовом этой функции необходимо захватить глобальную блокировку интерпретатора; после возврата она по-прежнему будет захвачена. Кроме того, при входе должно быть задано текущее состояние потока. В случае успеха возвращённое состояние потока устанавливается как текущее. Если субинтерпретатор создаётся с собственным ГИЛ, ГИЛ вызывающего интерпретатора будет освобождён. При возврате из функции ГИЛ нового интерпретатора будет захвачен текущим потоком, а ГИЛ предыдущего интерпретатора останется освобождённым.
Добавлено в версии 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()с конфигурацией, сохраняющей прежнее поведение. В результате создаётся неизолированный субинтерпретатор, который использует общий с основным интерпретатором ГИЛ, разрешает fork/exec, разрешает потоки-демоны и модули с однофазной инициализацией.
-
void Py_EndInterpreter(PyThreadState *tstate) -
Часть стабильного ABI.
Уничтожает (суб)интерпретатор, представленный указанным состоянием потока. Указанное состояние потока должно быть текущим. См. обсуждение состояний потоков ниже. После возврата вызова текущее состояние потока равно
NULL. Все состояния потоков, связанные с этим интерпретатором, уничтожаются. Перед вызовом этой функции необходимо захватить глобальную блокировку интерпретатора, связанного с целевым состоянием. После возврата ни один ГИЛ не захвачен.Py_FinalizeEx()уничтожит все субинтерпретаторы, которые к этому моменту не были уничтожены явно.
Отдельный ГИЛ для каждого интерпретатора
С помощью Py_NewInterpreterFromConfig() можно создать субинтерпретатор, полностью изолированный от других интерпретаторов, в том числе имеющий собственный ГИЛ. Главное преимущество такой изоляции заключается в том, что этот интерпретатор может выполнять код Python, не блокируясь другими интерпретаторами и не блокируя их. Таким образом, один процесс Python действительно может задействовать несколько ядер ЦП при выполнении кода Python. Изоляция также способствует использованию иного подхода к параллелизму, отличного от простого использования потоков. (См. PEP 554.)
При использовании изолированного интерпретатора необходимо тщательно следить за сохранением этой изоляции. В частности, нельзя совместно использовать объекты или изменяемое состояние без гарантий потокобезопасности. Обычно нельзя совместно использовать даже объекты, которые в остальном являются неизменяемыми (например, None, (1, 5)), из-за счётчика ссылок. Один из простых, но менее эффективных способов обойти это ограничение — использовать глобальную блокировку при любом обращении к некоторому состоянию (или объекту). В качестве альтернативы эффективно неизменяемые объекты (например, целые числа или строки) можно сделать безопасными, несмотря на счётчики ссылок, сделав их «бессмертными». Фактически это уже сделано для встроенных одиночных объектов, небольших целых чисел и ряда других встроенных объектов.
Если сохранить изоляцию, вы получите доступ к полноценным многопроцессорным вычислениям без сложностей, связанных с отсутствием блокировки потоков. Нарушение изоляции приведёт к полному спектру последствий работы без блокировки потоков, включая гонки данных и трудно диагностируемые сбои.
Помимо этого, одна из основных сложностей при использовании нескольких изолированных интерпретаторов — безопасная (без нарушения изоляции) и эффективная организация взаимодействия между ними. Пока что среда выполнения и стандартная библиотека не предлагают стандартного способа для этого. Будущий модуль стандартной библиотеки помог бы упростить сохранение изоляции и предоставил бы эффективные средства для обмена и совместного использования данных между интерпретаторами.
Добавлено в версии 3.12.
Ошибки и предостережения
Поскольку субинтерпретаторы (как и основной интерпретатор) являются частью одного процесса, изоляция между ними не идеальна: например, низкоуровневые файловые операции, такие как os.close(), могут (случайно или злонамеренно) повлиять на открытые файлы других интерпретаторов. Из-за особенностей совместного использования расширений (суб)интерпретаторами некоторые расширения могут работать некорректно; это особенно вероятно при однофазной инициализации или использовании глобальных переменных (static). Объекты, созданные в одном субинтерпретаторе, можно поместить в пространство имён другого (суб)интерпретатора; по возможности этого следует избегать.
Следует проявлять особую осторожность и не допускать совместного использования пользовательских функций, методов, экземпляров или классов между субинтерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут затронуть словарь загруженных модулей не того (суб)интерпретатора. Не менее важно избегать совместного использования объектов, из которых доступны перечисленные выше объекты.
Также обратите внимание, что сочетать эту функциональность с 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 не прерывается для рекурсивного выполнения другого асинхронного уведомления, но может прерываться для переключения потоков, если глобальная блокировка интерпретатора освобождена.Для выполнения этой функции не требуется текущее состояние потока или глобальная блокировка интерпретатора.
Чтобы вызвать эту функцию в субинтерпретаторе, вызывающий код должен удерживать ГИЛ. В противном случае функция func может быть запланирована для вызова не в том интерпретаторе.
Предупреждение
Это низкоуровневая функция, полезная только в самых особых случаях. Нет гарантии, что func будет вызвана как можно скорее. Если главный поток занят выполнением системного вызова, func не будет вызвана до завершения системного вызова. Эта функция, как правило, не подходит для вызова кода Python из произвольных потоков C. Вместо неё используйте API PyGILState.
Добавлено в версии 3.1.
Изменено в версии 3.9: Если эта функция вызывается в субинтерпретаторе, функция 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(но не функции профилирования), когда сообщается о событии номера строки. Его можно отключить для кадра, установивf_trace_linesэтого кадра в 0.
-
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.
Расширенная поддержка отладчиков
Эти функции предназначены только для использования расширенными средствами отладки.
-
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.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/c-api/init.html