Инициализация, завершение и потоки
См. также Конфигурация Python-инициализации.
Перед инициализацией Python
В приложении, подключающем Python, функция Py_Initialize() должна быть вызвана перед использованием любых других функций Python/C API; за исключением нескольких функций и глобальных переменных конфигурации.
Следующие функции можно безопасно вызывать до инициализации 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.Если флаг отличен от нуля, используйте
io.FileIOвместоio._WindowsConsoleIOдля стандартных потоковsys.Устанавливается в
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() -
Часть Стабильного API.
Инициализирует Python-интерпретатор. В приложениях, которые импортируют Python, это следует вызывать перед использованием любых других функций Python/C API; см. Перед инициализацией Python для некоторых исключений.
Инициализирует таблицу загруженных модулей (
sys.modules), и создает базовые модулиbuiltins,__main__иsys. Также инициализирует путь поиска модулей (sys.path). Не устанавливаетsys.argv; используйтеPySys_SetArgvEx()для этого. При повторном вызове (без предварительного вызоваPy_FinalizeEx()) является пустой операцией. Отсутствие возвращаемого значения; ошибка, если инициализация завершилась неудачно.Для настройки
Py_InitializeFromConfig()используйте функцию Конфигурация инициализации Python.Примечание
В Windows, изменяет режим консоли с
O_TEXTнаO_BINARY, что также повлияет на не-Python-использование консоли с помощью C Runtime.
-
void Py_InitializeEx(int initsigs) -
Часть Стабильного API.
Эта функция работает как
Py_Initialize(), если initsigs равно1. Если initsigs равно0, пропускает регистрацию обработки сигналов при инициализации, что может быть полезно при импортировании Python.Для настройки
Py_InitializeFromConfig()используйте функцию Конфигурация инициализации Python.
-
int Py_IsInitialized() -
Часть Стабильного API.
Возвращает true (ненулевое значение), если интерпретатор Python был инициализирован, и false (нуль), если нет. После вызова
Py_FinalizeEx(), возвращает false, пока не будет вызванPy_Initialize()снова.
-
int Py_FinalizeEx() -
Часть Стабильного API с версии 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() -
Часть Стабильного API.
Это обратная совместимая версия
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_*.См. также члены
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_*.См. также члены
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_*.Устарел начиная с версии 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), только тот поток, который вызвал разбиение, будет существовать. Это оказывает конкретное влияние как на то, как нужно обрабатывать блокировки, так и на всё сохранённое состояние в CPython runtime.
Тот факт, что остаётся только «текущий» поток, означает, что все блокировки, удерживаемые другими потоками, никогда не будут освобождены. Python решает эту проблему для os.fork(), приобретая блокировки, которые он использует внутри, перед разбиением, и освобождая их после. Кроме того, он сбрасывает любые Объекты блокировки в дочернем процессе. При расширении или внедрении Python нет способа сообщить Python об дополнительных (не-Python) блокировках, которые нужно получить перед или сбросить после разбиения. Для достижения того же результата необходимо использовать средства операционной системы, такие как pthread_atfork(). Кроме того, при расширении или внедрении Python вызов fork() напрямую, а не через os.fork() (и возврат к Python или вызов в Python) может привести к тупиковой ситуации, так как одна из внутренних блокировок Python будет удерживаться потоком, который не существует после разбиения. PyOS_AfterFork_Child() пытается сбросить необходимые блокировки, но не всегда может это сделать.
Тот факт, что все остальные потоки исчезают, также означает, что состояние runtime CPython там должно быть должным образом очищено, что и делает os.fork(). Это означает завершение всех других объектов PyThreadState, принадлежащих текущему интерпретатору, и всех других объектов PyInterpreterState. Из-за этого и из-за особой природы “главного” интерпретатора, fork() следует вызывать только в «главном» потоке этого интерпретатора, где изначально был инициирован CPython глобальный runtime. Исключением является тот случай, если 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.
Убеждается, что текущий поток готов к вызову API Python C независимо от текущего состояния Python или глобальной блокировки интерпретатора. Это можно вызывать столько раз, сколько нужно, пока каждый вызов соответствует вызову
PyGILState_Release(). В общем случае, другие API, связанные с потоками, могут использоваться между вызовамиPyGILState_Ensure()иPyGILState_Release(), при условии, что состояние потока восстанавливается до предыдущего состояния перед вызовом 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в противном случае. Эту функцию можно вызывать из любого потока в любое время. Только если у него есть состояние потока Python и он в данный момент держит GIL, он вернёт1. В основном это вспомогательная/диагностическая функция. Она может быть полезна, например, в контекстах обратного вызова или функциях выделения памяти, когда знание того, что блокировка 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.
Создает новый объект состояния интерпретатора. Глобальная блокировка интерпретатора (GIL) не должна быть захвачена, но может быть захвачена, если это необходимо для сериализации вызовов этой функции.
Вызывает событие аудита
cpython.PyInterpreterState_Newбез аргументов.
-
void PyInterpreterState_Clear(PyInterpreterState *interp) -
Часть Стабильной ABI.
Сбрасывает всю информацию в объекте состояния интерпретатора. Глобальная блокировка интерпретатора (GIL) должна быть захвачена.
Вызывает событие аудита
cpython.PyInterpreterState_Clearбез аргументов.
-
void PyInterpreterState_Delete(PyInterpreterState *interp) -
Часть Стабильной ABI.
Уничтожает объект состояния интерпретатора. Глобальная блокировка интерпретатора (GIL) не должна быть захвачена. Состояние интерпретатора должно быть сброшено предыдущим вызовом
PyInterpreterState_Clear().
-
PyThreadState *PyThreadState_New(PyInterpreterState *interp) -
Часть Стабильной ABI.
Создает новый объект состояния потока, принадлежащий заданному объекту интерпретатора. Глобальная блокировка интерпретатора (GIL) не должна быть захвачена, но может быть захвачена, если это необходимо для сериализации вызовов этой функции.
-
void PyThreadState_Clear(PyThreadState *tstate) -
Часть Стабильной ABI.
Сбрасывает всю информацию в объекте состояния потока. Глобальная блокировка интерпретатора (GIL) должна быть захвачена.
Изменено в версии 3.9: Эта функция теперь вызывает обратный вызов
PyThreadState.on_delete. Ранее это происходило вPyThreadState_Delete().
-
void PyThreadState_Delete(PyThreadState *tstate) -
Часть Стабильной ABI.
Уничтожает объект состояния потока. Глобальная блокировка интерпретатора (GIL) не должна быть захвачена. Состояние потока должно быть сброшено предыдущим вызовом
PyThreadState_Clear().
-
void PyThreadState_DeleteCurrent(void) -
Уничтожает текущее состояние потока и освобождает глобальную блокировку интерпретатора. Как и в
PyThreadState_Delete(), глобальная блокировка интерпретатора (GIL) не должна быть захвачена. Состояние потока должно быть сброшено предыдущим вызовом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() -
Возвращаемое значение: Заимствованная ссылка. Часть Стабильного API.
Возвращает словарь, в котором расширения могут хранить информацию о состоянии, специфичной для потока. Каждое расширение должно использовать уникальный ключ для хранения состояния в словаре. Можно вызывать эту функцию, когда состояние текущего потока недоступно. Если эта функция возвращает
NULL, исключение не было возбуждено, и вызывающая сторона должна предположить, что состояние текущего потока недоступно.
-
int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) -
Часть Стабильного API.
Асинхронно вызывает исключение в потоке. Аргумент id — идентификатор целевого потока; exc — объект исключения, подлежащий возбуждению. Эта функция не захватывает никакие ссылки на exc. Для предотвращения небрежного использования необходимо написать собственное расширение на C для вызова этой функции. Должна вызываться с захваченным глобальным интерпретатором. Возвращает количество изменённых состояний потоков; обычно это один, но будет ноль, если идентификатор потока не найден. Если exc —
NULL, ожидаемое исключение (если таковое имеется) для потока очищается. Исключений не генерирует.Изменено в версии 3.7: Тип параметра id изменён с long на unsigned long.
-
void PyEval_AcquireThread(PyThreadState *tstate) -
Часть Стабильного API.
Захватывает глобальную блокировку интерпретатора и устанавливает состояние текущего потока в 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) -
Часть Стабильного API.
Сбрасывает состояние текущего потока до
NULLи освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и должна удерживаться текущим потоком. Аргумент tstate, который не должен бытьNULL, используется только для проверки, что он представляет состояние текущего потока — если это не так, сообщается об ошибке.PyEval_SaveThread()— функция более высокого уровня, которая всегда доступна (даже когда потоки не были инициализированы).
-
void PyEval_AcquireLock() -
Часть Стабильного API.
Захватывает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее. Если этот поток уже имеет блокировку, возникает тупиковая ситуация.
Устарело начиная с версии 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() -
Часть Стабильного API.
Освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее.
Устарело начиная с версии 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 -
Это определяет работу 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; исключение не устанавливается, так как состояние исключения хранится в текущем состоянии потока, и может быть нет текущего состояния потока.Как и все другие функции API Python/C, перед вызовом этой функции должен быть захвачен глобальный замок интерпретатора, и он всё ещё захвачен, когда функция возвращает управление. Аналогично, текущее состояние потока должно быть установлено при входе. При успехе возвращённое состояние потока будет установлено как текущее. Если под-интерпретатор создаётся со своим собственным блокировкой 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 = Py_NewInterpreterFromConfig(&config);Обратите внимание, что конфигурация используется только кратковременно и не модифицируется. Во время инициализации значения конфигурации преобразуются в различные значения
PyInterpreterState. Читать-только копия конфигурации может быть сохранена внутриPyInterpreterState.Модули расширений совместно используются между (под-)интерпретаторами следующим образом:
- Для модулей, использующих многофазную инициализацию, например
PyModule_FromDefAndSpec(), для каждого интерпретатора создаётся и инициализируется отдельный объект модуля. Только переменные уровня C и глобальные переменные совместно используются между этими объектами модулей. -
Для модулей, использующих однофазную инициализацию, например
PyModule_Create(), в первый раз, когда определённое расширение импортируется, оно инициализируется обычно, и (поверхностная) копия словаря модуля скрывается. Когда то же самое расширение импортируется другим (под-)интерпретатором, инициализируется новый модуль и заполняется содержимым этой копии; функция расширенияinitне вызывается. Таким образом, объекты в словаре модуля в итоге разделяются между (под-)интерпретаторами, что может вызвать нежелательное поведение (см. Проблемы и замечания ниже).Обратите внимание, что это отличается от того, что происходит, когда расширение импортируется после того, как интерпретатор был полностью повторно инициализирован вызовом
Py_FinalizeEx()иPy_Initialize(); в этом случае функция расширенияinitmoduleвызывается снова. Как и при многофазной инициализации, это означает, что только переменные уровня C и глобальные переменные совместно используются между этими модулями.
- Для модулей, использующих многофазную инициализацию, например
-
PyThreadState *Py_NewInterpreter(void) -
Часть Стабильной ABI.
Создать новый под-интерпретатор. Это по существу просто оболочка вокруг
Py_NewInterpreterFromConfig()с конфигурацией, сохраняющей существующее поведение. Результатом является под-интерпретатор без изоляции, который разделяет GIL основного интерпретатора, допускает fork/exec, позволяет демоническим потокам и разрешает модули с однофазной инициализацией.
-
void Py_EndInterpreter(PyThreadState *tstate) -
Часть Стабильной ABI.
Уничтожить (под-)интерпретатор, представленный данным состоянием потока. Данное состояние потока должно быть текущим состоянием потока. См. обсуждение состояний потоков ниже. После возврата вызова, текущее состояние потока
NULL. Все состояния потоков, связанные с этим интерпретатором, уничтожаются. Глобальный замок интерпретатора, используемый целевым интерпретатором, должен быть захвачен перед вызовом этой функции. Никакая блокировка GIL не удерживается при возврате.Py_FinalizeEx()уничтожит все под-интерпретаторы, которые не были явно уничтожены на этом этапе.
Блокировка GIL на интерпретатор
Используя Py_NewInterpreterFromConfig(), вы можете создать под-интерпретатор, который полностью изолирован от других интерпретаторов, включая собственную блокировку GIL. Наиболее важным преимуществом этой изоляции является то, что такой интерпретатор может выполнять код Python без блокировки другими интерпретаторами или блокировки других. Таким образом, один процесс Python может по-настоящему использовать несколько ядер процессора при выполнении кода Python. Изоляция также поощряет другой подход к параллелизму, отличный от простого использования потоков. (См. PEP 554.)
Использование изолированного интерпретатора требует внимательности в сохранении этой изоляции. Это особенно относится к совместному использованию любых объектов или изменяемых состояний без гарантий о потоковой безопасности. Даже объекты, которые в противном случае являются неизменяемыми (например, None, (1, 5)) обычно не могут быть совместно использованы из-за счётчика ссылок. Один простой, но менее эффективный подход к этому — использовать глобальную блокировку вокруг всех обращений к какому-либо состоянию (или объекту). В качестве альтернативы, эффективно неизменяемые объекты (например, целые числа или строки) могут быть защищены независимо от счётчиков ссылок, сделав их «бессмертными». Фактически, это было сделано для встроенных одиночных объектов, малых целых чисел и ряда других встроенных объектов.
Если вы сохраняете изоляцию, то вы получите доступ к правильному многоядерному вычислению без сложностей, связанных со свободными потоками. Отсутствие сохранения изоляции подвергнет вас всем последствиям свободных потоков, включая гонки и трудноотлаживаемые сбои.
Помимо этого, одной из основных проблем использования нескольких изолированных интерпретаторов является то, как безопасно (не нарушая изоляцию) и эффективно общаться между ними. В настоящее время в среде выполнения и стандартной библиотеке нет стандартного подхода к этому. Будущий модуль стандартной библиотеки поможет минимизировать усилия по сохранению изоляции и обеспечит эффективные инструменты для обмена данными между интерпретаторами.
Добавлена в версии 3.12.
Проблемы и замечания
Поскольку под-интерпретаторы (и основной интерпретатор) являются частью одного процесса, изоляция между ними не является идеальной — например, при использовании низкоуровневых операций с файлами, таких как os.close(), они могут (случайно или злонамеренно) влиять на открытые файлы друг друга. Из-за того, как расширения совместно используются между (под-)интерпретаторами, некоторые расширения могут работать неправильно; это особенно вероятно при использовании однофазной инициализации или (статических) глобальных переменных. Возможно, что объекты, созданные в одном под-интерпретаторе, могут быть вставлены в пространство имён другого (под-)интерпретатора; этого следует избегать, если это возможно.
Особое внимание следует уделить тому, чтобы избежать совместного использования пользовательских функций, методов, экземпляров или классов между под-интерпретаторами, так как операции импорта, выполненные такими объектами, могут повлиять на словарь загруженных модулей не того (под-)интерпретатора. Также важно избегать совместного использования объектов, до которых можно добраться из вышеперечисленных.
Также обратите внимание, что объединение этой функциональности с API PyGILState_* API является тонким, поскольку эти 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 теперь планируется для вызова из подинтерпретатора, а не из основного интерпретатора. Каждый подинтерпретатор теперь имеет свой собственный список запланированных вызовов.
Профилирование и отслеживание
Интерпретатор 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(но не функций профилирования) при выполнении нового кода операции. Это событие по умолчанию не генерируется: оно должно быть явно запрошено путем установкиf_trace_opcodesв 1 в фрейме.
-
void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) -
Установить функцию профилирования на func. Параметр obj передается функции как первый параметр и может быть любым объектом Python или
NULL. Если функции профилирования нужно сохранять состояние, использование различных значений obj для каждого потока предоставляет удобное и безопасное место для его хранения. Функция профилирования вызывается для всех отслеживаемых событий, кромеPyTrace_LINEPyTrace_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), которая оборачивает базовую реализацию native TLS для поддержки API локального хранения данных на уровне Python (threading.local). API C-уровня CPython подобны тем, которые предлагаются 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.
Освобождает заданный ключ, выделенный
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