Инициализация, завершение и потоки¶
Смотрите также Python Initialization Configuration.
Перед инициализацией Python¶
В приложении, использующем Python, функция Py_Initialize()
должна быть вызвана перед использованием любых других функций API Python/C; за исключением нескольких функций и global configuration variables.
Следующие функции могут быть безопасно вызваны до инициализации Python:
Функции настройки:
Информативные функции:
Коммунальные услуги:
Распределители памяти:
Примечание
Следующие функции ** не должны вызываться ** перед Py_Initialize()
: Py_EncodeLocale()
, Py_GetPath()
, Py_GetPrefix()
, Py_GetExecPrefix()
, Py_GetProgramFullPath()
, Py_GetPythonHome()
, Py_GetProgramName()
и PyEval_InitThreads()
.
Глобальные переменные конфигурации¶
В Python есть переменные для глобальной конфигурации, которые управляют различными функциями и опциями. По умолчанию эти флаги управляются значением command line options.
Когда флажок устанавливается с помощью параметра, значение флага равно количеству раз, когда этот параметр был установлен. Например, -b
устанавливает значение Py_BytesWarningFlag
равным 1, а -bb
устанавливает значение Py_BytesWarningFlag
равным 2.
-
int Py_BytesWarningFlag¶
Выдает предупреждение при сравнении
bytes
илиbytearray
сstr
илиbytes
сint
. Выдает ошибку, если значение больше или равно2
.Устанавливается с помощью параметра
-b
.
-
int Py_DebugFlag¶
Включите вывод отладки синтаксического анализатора (только для экспертов, в зависимости от параметров компиляции).
Устанавливается с помощью параметра
-d
и переменной окруженияPYTHONDEBUG
.
-
int Py_DontWriteBytecodeFlag¶
Если установлено ненулевое значение, Python не будет пытаться записывать файлы
.pyc
при импорте исходных модулей.Устанавливается с помощью параметра
-B
и переменной окруженияPYTHONDONTWRITEBYTECODE
.
-
int Py_FrozenFlag¶
Подавляйте сообщения об ошибках при вычислении пути поиска модуля в
Py_GetPath()
.Закрытый флаг, используемый программами
_freeze_module
иfrozenmain
.
-
int Py_HashRandomizationFlag¶
Присваивается значение
1
, если переменной окруженияPYTHONHASHSEED
присвоено значение непустой строки.Если флаг отличен от нуля, считайте переменную окружения
PYTHONHASHSEED
, чтобы инициализировать начальное значение секретного хэша.
-
int Py_IgnoreEnvironmentFlag¶
Игнорируйте все
PYTHON*
переменные окружения, напримерPYTHONPATH
иPYTHONHOME
, которые могут быть установлены.
-
int Py_InspectFlag¶
Когда в качестве первого аргумента передается сценарий или используется параметр
-c
, после выполнения сценария или команды перейдите в интерактивный режим, даже еслиsys.stdin
не отображается как терминал.Устанавливается с помощью параметра
-i
и переменной окруженияPYTHONINSPECT
.
-
int Py_IsolatedFlag¶
Запустите Python в изолированном режиме. В изолированном режиме
sys.path
не содержит ни каталога скрипта, ни каталога пользовательских пакетов сайта.Устанавливается с помощью параметра
-I
.Добавлено в версии 3.4.
-
int Py_LegacyWindowsFSEncodingFlag¶
Если флаг отличен от нуля, используйте кодировку
mbcs
с обработчиком ошибокreplace
вместо кодировки UTF-8 с обработчиком ошибокsurrogatepass
для filesystem encoding and error handler.Присваивается значение
1
, если переменной окруженияPYTHONLEGACYWINDOWSFSENCODING
присвоено значение непустой строки.Смотрите PEP 529 для получения более подробной информации.
Availability: Окна.
-
int Py_LegacyWindowsStdioFlag¶
Если флаг отличен от нуля, используйте
io.FileIO
вместоio._WindowsConsoleIO
дляsys
стандартных потоков.Присваивается значение
1
, если переменной окруженияPYTHONLEGACYWINDOWSSTDIO
присвоено значение непустой строки.Смотрите PEP 528 для получения более подробной информации.
Availability: Окна.
-
int Py_NoSiteFlag¶
Отключите импорт модуля
site
и связанные с ним зависящие от сайта манипуляции сsys.path
. Также отключите эти манипуляции, еслиsite
будет явно импортирован позже (вызовитеsite.main()
, если вы хотите, чтобы они были запущены).Устанавливается с помощью параметра
-S
.
-
int Py_NoUserSiteDirectory¶
Не добавляйте
user site-packages directory
кsys.path
.Устанавливается с помощью параметров
-s
и-I
, а также переменной окруженияPYTHONNOUSERSITE
.
-
int Py_OptimizeFlag¶
Устанавливается с помощью параметра
-O
и переменной окруженияPYTHONOPTIMIZE
.
-
int Py_QuietFlag¶
Не отображайте сообщения об авторских правах и версии даже в интерактивном режиме.
Устанавливается с помощью параметра
-q
.Добавлено в версии 3.2.
-
int Py_UnbufferedStdioFlag¶
Принудительно отключите буферизацию потоков stdout и stderr.
Устанавливается с помощью параметра
-u
и переменной окруженияPYTHONUNBUFFERED
.
-
int Py_VerboseFlag¶
При каждой инициализации модуля выводите сообщение с указанием места (имени файла или встроенного модуля), из которого он был загружен. Если значение больше или равно
2
, выводите сообщение для каждого файла, наличие которого проверяется при поиске модуля. Также содержит информацию об очистке модуля при выходе.Устанавливается с помощью параметра
-v
и переменной окруженияPYTHONVERBOSE
.
Инициализация и завершение работы интерпретатора¶
-
void Py_Initialize()¶
- Part of the Стабильный ABI.
Инициализируйте интерпретатор Python. В приложении, использующем Python, это следует вызывать перед использованием любых других функций API Python/C ; несколько исключений приведены в разделе Before Python Initialization.
Это инициализирует таблицу загруженных модулей (
sys.modules
), и создает основные модулиbuiltins
,__main__
иsys
. Это также инициализирует путь поиска модуля (sys.path
). Он не задаетsys.argv
; для этого используйтеPySys_SetArgvEx()
. При повторном вызове это не выполняется (без предварительного вызоваPy_FinalizeEx()
). Возвращаемое значение отсутствует; в случае сбоя инициализации это приводит к фатальной ошибке.Примечание
В Windows измените режим консоли с
O_TEXT
наO_BINARY
, что также повлияет на использование консоли не на Python с использованием среды выполнения C.
-
void Py_InitializeEx(int initsigs)¶
- Part of the Стабильный ABI.
Эта функция работает следующим образом
Py_Initialize()
, если инициализация равна1
. Если initsigs равен0
, он пропускает регистрацию инициализации обработчиков сигналов, что может быть полезно при внедрении Python.
-
int Py_IsInitialized()¶
- Part of the Стабильный ABI.
Возвращает значение true (отличное от нуля), если интерпретатор Python был инициализирован, и значение false (ноль), если нет. После вызова
Py_FinalizeEx()
это возвращает значение false до тех пор, пока снова не будет вызванPy_Initialize()
.
-
int Py_FinalizeEx()¶
- Part of the Стабильный ABI since version 3.6.
Отмените все инициализации, выполненные с помощью
Py_Initialize()
и последующее использование функций API Python/C, и уничтожьте все вспомогательные интерпретаторы (см.Py_NewInterpreter()
ниже), которые были созданы и еще не уничтожены с момента последнего вызоваPy_Initialize()
. В идеале, это освобождает всю память, выделенную интерпретатором Python. При повторном вызове эта операция не выполняется (без повторного вызоваPy_Initialize()
). Обычно возвращаемое значение равно0
. Если во время завершения были допущены ошибки (сброс буферизованных данных), возвращается-1
.Эта функция предусмотрена по ряду причин. Встраиваемое приложение может захотеть перезапустить Python без необходимости перезапуска самого приложения. Приложение, которое загрузило интерпретатор Python из динамически загружаемой библиотеки (или DLL-библиотеки), может захотеть освободить всю память, выделенную Python, перед выгрузкой библиотеки DLL. Во время поиска утечек памяти в приложении разработчик может захотеть освободить всю память, выделенную Python, перед выходом из приложения.
** Ошибки и предостережения:** Уничтожение модулей и объектов в модулях выполняется в случайном порядке; это может привести к сбою деструкторов (
__del__()
методов), если они зависят от других объектов (даже функций) или модулей. Динамически загружаемые модули расширения, загруженные с помощью Python, не выгружаются. Небольшие объемы памяти, выделенные интерпретатором Python, могут не освобождаться (если вы обнаружите утечку, пожалуйста, сообщите об этом). Память, связанная циклическими ссылками между объектами, не освобождается. Часть памяти, выделенная модулями расширения, может не освобождаться. Некоторые расширения могут работать некорректно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение вызываетPy_Initialize()
иPy_FinalizeEx()
более одного раза.Выдает auditing event
cpython._PySys_ClearAuditHooks
без каких-либо аргументов.Добавлено в версии 3.6.
-
void Py_Finalize()¶
- Part of the Стабильный ABI.
Это обратно совместимая версия
Py_FinalizeEx()
, которая игнорирует возвращаемое значение.
Параметры всего процесса¶
-
int Py_SetStandardStreamEncoding(const char *encoding, const char *errors)¶
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать настройки
PyConfig.stdio_encoding
иPyConfig.stdio_errors
, см. Python Initialization Configuration.Эта функция должна быть вызвана перед
Py_Initialize()
, если она вообще вызывается. Она определяет, какую кодировку и обработку ошибок использовать при стандартном вводе-выводе, с теми же значениями, что и вstr.encode()
.Он переопределяет значения
PYTHONIOENCODING
и позволяет внедрять код для управления кодировкой ввода-вывода, когда переменная окружения не работает.кодировка и/или ошибки могут быть
NULL
при использованииPYTHONIOENCODING
и/или значений по умолчанию (в зависимости от других настроек).Обратите внимание, что
sys.stderr
всегда использует обработчик ошибок «backslashreplace», независимо от этого (или любого другого) параметра.Если вызывается
Py_FinalizeEx()
, эту функцию нужно будет вызвать еще раз, чтобы повлиять на последующие вызовыPy_Initialize()
.Возвращает
0
в случае успеха, ненулевое значение при ошибке (например, вызов после того, как интерпретатор уже был инициализирован).Добавлено в версии 3.4.
Не рекомендуется, начиная с версии 3.11.
-
void Py_SetProgramName(const wchar_t *name)¶
- Part of the Стабильный ABI.
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать параметр
PyConfig.program_name
, см. Python Initialization Configuration.Эта функция должна быть вызвана до того, как
Py_Initialize()
будет вызвана в первый раз, если она вообще будет вызвана. Он сообщает интерпретатору значение аргументаargv[0]
для функцииmain()
программы (преобразуется в расширенные символы). Это используетсяPy_GetPath()
и некоторыми другими функциями, приведенными ниже, для поиска библиотек среды выполнения Python относительно исполняемого файла интерпретатора. Значение по умолчанию -'python'
. Аргумент должен указывать на завершающуюся нулем строку символов в статическом хранилище, содержимое которой не будет изменяться в течение всего времени выполнения программы. Никакой код в интерпретаторе Python не изменит содержимое этого хранилища.Используйте
Py_DecodeLocale()
для декодирования строки в байтах, чтобы получить строку wchar_*.Не рекомендуется, начиная с версии 3.11.
-
wchar_t *Py_GetProgramName()¶
- Part of the Стабильный ABI.
Возвращает имя программы, заданное с помощью
Py_SetProgramName()
, или значение по умолчанию. Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение.Эта функция не должна вызываться перед
Py_Initialize()
, в противном случае она возвращаетNULL
.Изменено в версии 3.10: Теперь он возвращает
NULL
, если вызывался ранееPy_Initialize()
.
-
wchar_t *Py_GetPrefix()¶
- Part of the Стабильный 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()¶
- Part of the Стабильный ABI.
Возвращает префикс *exec- для установленных файлов, зависящих от платформы. Это определяется с помощью ряда сложных правил из имени программы, заданного с помощью
Py_SetProgramName()
и некоторых переменных окружения; например, если имя программы'/usr/local/bin/python'
, префикс exec равен'/usr/local'
. Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Это соответствует переменной exec_prefix в скрипте верхнего уровняMakefile
и аргументу--exec-prefix
для скрипта configure во время сборки. Это значение доступно для кода на Python какsys.exec_prefix
. Оно полезно только в Unix.Справочная информация: Префикс exec- отличается от префикса prefix, когда файлы, зависящие от платформы (такие как исполняемые файлы и общие библиотеки), установлены в другом дереве каталогов. При обычной установке файлы, зависящие от платформы, могут быть установлены в поддереве
/usr/local/plat
, в то время как независимые от платформы файлы могут быть установлены в поддереве/usr/local
.Вообще говоря, платформа - это комбинация семейств аппаратного и программного обеспечения, например, компьютеры Sparc под управлением операционной системы Solaris 2.x считаются одной и той же платформой, но компьютеры Intel под управлением Solaris 2.x - это другая платформа, а компьютеры Intel под управлением Linux - еще одна платформа. Различные основные версии одной и той же операционной системы, как правило, также используются на разных платформах. Операционные системы, отличные от Unix, - это другая история; стратегии установки в этих системах настолько различны, что префикс и exec-prefix не имеют смысла и устанавливаются в пустую строку. Обратите внимание, что скомпилированные файлы байт-кода Python не зависят от платформы (но не зависят от версии Python, в которой они были скомпилированы!).
Системные администраторы будут знать, как настроить mount или automount программы для совместного использования
/usr/local
между платформами при использовании/usr/local/plat
отдельной файловой системы для каждой платформы.Эта функция не должна вызываться перед
Py_Initialize()
, в противном случае она возвращаетNULL
.Изменено в версии 3.10: Теперь он возвращает
NULL
, если вызывался ранееPy_Initialize()
.
-
wchar_t *Py_GetProgramFullPath()¶
- Part of the Стабильный ABI.
Возвращает полное имя программы исполняемого файла Python; это вычисляется как побочный эффект получения пути поиска модуля по умолчанию из имени программы (заданного с помощью
Py_SetProgramName()
выше). Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Значение доступно для кода на Python какsys.executable
.Эта функция не должна вызываться перед
Py_Initialize()
, в противном случае она возвращаетNULL
.Изменено в версии 3.10: Теперь он возвращает
NULL
, если вызывался ранееPy_Initialize()
.
-
wchar_t *Py_GetPath()¶
- Part of the Стабильный ABI.
Возвращает путь поиска модуля по умолчанию; он вычисляется из названия программы (заданного с помощью
Py_SetProgramName()
выше) и некоторых переменных среды. Возвращаемая строка состоит из последовательности имен каталогов, разделенных символом-разделителем, зависящим от платформы. Символом-разделителем является':'
в Unix и macOS,';'
в Windows. Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Списокsys.path
инициализируется этим значением при запуске интерпретатора; он может быть изменен (и обычно так и делается) позже, чтобы изменить путь поиска для загрузки модулей.Эта функция не должна вызываться перед
Py_Initialize()
, в противном случае она возвращаетNULL
.Изменено в версии 3.10: Теперь он возвращает
NULL
, если вызывался ранееPy_Initialize()
.
-
void Py_SetPath(const wchar_t*)¶
- Part of the Стабильный ABI since version 3.7.
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать настройки
PyConfig.module_search_paths
иPyConfig.module_search_paths_set
, см. Python Initialization Configuration.Задайте путь поиска модуля по умолчанию. Если эта функция вызывается перед
Py_Initialize()
, тоPy_GetPath()
не будет пытаться вычислить путь поиска по умолчанию, а будет использовать предоставленный путь. Это полезно, если Python встроен в приложение, которое полностью осведомлено о расположении всех модулей. Компоненты path должны быть разделены символом-разделителем, зависящим от платформы, который в Unix и macOS равен':'
, а в Windows -';'
.Это также приводит к тому, что для
sys.executable
устанавливается значение полного пути к программе (см. : c:func:Py_GetProgramFullPath), а дляsys.prefix
иsys.exec_prefix
значение пустое. Вызывающий абонент может изменить их, если потребуется, после вызова:c:func:Py_Initialize.Используйте
Py_DecodeLocale()
для декодирования строки в байтах, чтобы получить строку wchar_*.Аргумент path копируется внутренне, поэтому вызывающий может освободить его после завершения вызова.
Изменено в версии 3.8: Полный путь к программе теперь используется для
sys.executable
вместо названия программы.Не рекомендуется, начиная с версии 3.11.
-
const char *Py_GetVersion()¶
- Part of the Стабильный 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()¶
- Part of the Стабильный ABI.
Возвращает идентификатор платформы для текущей платформы. В Unix это значение формируется из «официального» названия операционной системы, преобразованного в нижний регистр, за которым следует основной номер версии; например, для Solaris 2.x, который также известен как SunOS 5.x, значение равно
'sunos5'
. В macOS это'darwin'
. В Windows это'win'
. Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Значение доступно для кода на Python какsys.platform
.
-
const char *Py_GetCopyright()¶
- Part of the Стабильный ABI.
Возвращает официальную строку авторских прав для текущей версии Python, например
'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'
Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Значение доступно для кода на Python как
sys.copyright
.
-
const char *Py_GetCompiler()¶
- Part of the Стабильный ABI.
Возвращает указание на компилятор, используемый для сборки текущей версии Python, например, в квадратных скобках:
"[GCC 2.7.2.2]"
Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Значение доступно для кода на Python как часть переменной
sys.version
.
-
const char *Py_GetBuildInfo()¶
- Part of the Стабильный ABI.
Возвращает информацию о порядковом номере, дате и времени сборки текущего экземпляра интерпретатора Python, например
"#67, Aug 1 1997, 22:34:28"
Возвращаемая строка указывает на статическое хранилище; вызывающий объект не должен изменять ее значение. Значение доступно для кода на Python как часть переменной
sys.version
.
-
void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)¶
- Part of the Стабильный ABI.
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать параметры
PyConfig.argv
,PyConfig.parse_argv
иPyConfig.safe_path
, см. Python Initialization Configuration.Установите
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 Initialization Configuration.Примечание
Рекомендуется, чтобы приложения, использующие интерпретатор 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)¶
- Part of the Стабильный ABI.
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать настройки
PyConfig.argv
иPyConfig.parse_argv
, см. Python Initialization Configuration.Эта функция работает следующим образом
PySys_SetArgvEx()
с параметром updatepath, равным1
, если только интерпретатор python не был запущен с параметром-I
.Используйте
Py_DecodeLocale()
для декодирования строки в байтах, чтобы получить строку wchar_*.Смотрите также
PyConfig.orig_argv
иPyConfig.argv
члены группы Python Initialization Configuration.Изменено в версии 3.4: Значение updatepath зависит от
-I
.Не рекомендуется, начиная с версии 3.11.
-
void Py_SetPythonHome(const wchar_t *home)¶
- Part of the Стабильный ABI.
Этот API сохранен для обеспечения обратной совместимости: вместо него следует использовать параметр
PyConfig.home
, см. Python Initialization Configuration.Задайте «домашний» каталог по умолчанию, то есть расположение стандартных библиотек Python. Значение строки аргумента смотрите в
PYTHONHOME
.Аргумент должен указывать на завершающуюся нулем символьную строку в статическом хранилище, содержимое которой не изменится в течение всего времени выполнения программы. Никакой код в интерпретаторе Python не изменит содержимое этого хранилища.
Используйте
Py_DecodeLocale()
для декодирования строки в байтах, чтобы получить строку wchar_*.Не рекомендуется, начиная с версии 3.11.
-
wchar_t *Py_GetPythonHome()¶
- Part of the Стабильный ABI.
Возвращает значение по умолчанию «home», то есть значение, установленное предыдущим вызовом
Py_SetPythonHome()
, или значение переменной окруженияPYTHONHOME
, если она установлена.Эта функция не должна вызываться перед
Py_Initialize()
, в противном случае она возвращаетNULL
.Изменено в версии 3.10: Теперь он возвращает
NULL
, если вызывался ранееPy_Initialize()
.
Состояние потока и глобальная блокировка интерпретатора¶
Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python существует глобальная блокировка, называемая global interpreter lock или GIL, которая должна удерживаться текущим потоком, прежде чем он сможет безопасно обращаться к объектам Python. Без блокировки даже простейшие операции могут вызвать проблемы в многопоточной программе: например, когда два потока одновременно увеличивают количество ссылок на один и тот же объект, количество ссылок может в конечном итоге увеличиться только один раз вместо двух.
Следовательно, существует правило, согласно которому только тот поток, который получил GIL, может работать с объектами Python или вызывать функции API Python/C. Чтобы имитировать параллельность выполнения, интерпретатор регулярно пытается переключать потоки (см. 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 поддерживает создание дополнительных интерпретаторов (используя : c:func:Py_NewInterpreter), но смешивание нескольких интерпретаторов и API PyGILState_*
не поддерживается.
Будьте осторожны с fork()¶
Еще одна важная вещь, на которую следует обратить внимание в отношении потоков, - это их поведение при вызове C fork()
. В большинстве систем с fork()
После разветвления процесса будет существовать только поток, который выдал разветвление. Это оказывает конкретное влияние как на то, как должны обрабатываться блокировки, так и на все сохраненное состояние во время выполнения Cpython.
Тот факт, что остается только «текущий» поток, означает, что любые блокировки, удерживаемые другими потоками, никогда не будут сняты. Python решает эту проблему для os.fork()
, получая блокировки, которые он использует внутренне перед fork, и снимая их впоследствии. Кроме того, он сбрасывает все Блокировка объектов в дочернем элементе. При расширении или внедрении Python нет способа сообщить Python о дополнительных (не связанных с Python) блокировках, которые необходимо получить до или сбросить после разветвления. Для достижения той же цели необходимо было бы использовать такие средства операционной системы, как: c:func:!pthread_atfork. Кроме того, при расширении или внедрении Python вызов fork()
напрямую, а не через os.fork()
(и возврат к Python или вызов в Python) может привести к взаимоблокировке из-за того, что одна из внутренних блокировок Python удерживается потоком, который перестал функционировать после fork. PyOS_AfterFork_Child()
пытается сбросить необходимые блокировки, но не всегда это удается.
Тот факт, что все остальные потоки удаляются, также означает, что состояние выполнения Cpython должно быть должным образом очищено, что и делает os.fork()
. Это означает завершение всех остальных объектов PyThreadState
, принадлежащих текущему интерпретатору, и всех остальных объектов PyInterpreterState
. Из-за этого и особого характера «main» interpreter, fork()
должен вызываться только в «главном» потоке интерпретатора, где изначально была инициализирована глобальная среда выполнения CPython. Единственное исключение - это если exec()
будет вызван сразу после этого.
Высокоуровневый API¶
Это наиболее часто используемые типы и функции при написании кода расширения C или при внедрении интерпретатора Python:
-
type PyInterpreterState¶
- Part of the Ограниченный API (as an opaque struct).
Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, совместно используют управление модулем и некоторые другие внутренние элементы. В этой структуре нет открытых элементов.
Потоки, принадлежащие разным интерпретаторам, изначально не имеют общего доступа ни к чему, кроме состояния процесса, такого как доступная память, открытые файловые дескрипторы и тому подобное. Глобальная блокировка интерпретатора также является общей для всех потоков, независимо от того, к какому интерпретатору они принадлежат.
-
type PyThreadState¶
- Part of the Ограниченный API (as an opaque struct).
Эта структура данных представляет состояние отдельного потока. Единственным общедоступным элементом данных является:
-
PyInterpreterState *interp¶
Состояние интерпретатора этого потока.
-
PyInterpreterState *interp¶
-
void PyEval_InitThreads()¶
- Part of the Стабильный ABI.
Устаревшая функция, которая ничего не делает.
В Python 3.6 и более ранних версиях эта функция создавала GIL, если он не существовал.
Изменено в версии 3.9: Теперь эта функция ничего не делает.
Изменено в версии 3.7: Эта функция теперь вызывается с помощью : c:func:Py_Initialize(), так что вам больше не нужно вызывать ее самостоятельно.
Изменено в версии 3.2: Эта функция больше не может быть вызвана до
Py_Initialize()
.Не рекомендуется, начиная с версии 3.9.
-
int PyEval_ThreadsInitialized()¶
- Part of the Стабильный ABI.
Возвращает ненулевое значение, если было вызвано
PyEval_InitThreads()
. Эта функция может быть вызвана без удержания GIL и, следовательно, может использоваться для предотвращения вызовов API блокировки при выполнении однопоточной работы.Изменено в версии 3.7: GIL Теперь инициализируется с помощью
Py_Initialize()
.Не рекомендуется, начиная с версии 3.9.
-
PyThreadState *PyEval_SaveThread()¶
- Part of the Стабильный ABI.
Снимите глобальную блокировку интерпретатора (если она была создана) и сбросьте состояние потока на
NULL
, вернув предыдущее состояние потока (которое не являетсяNULL
). Если блокировка была создана, текущий поток, должно быть, получил ее.
-
void PyEval_RestoreThread(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Получите глобальную блокировку интерпретатора (если она была создана) и установите для состояния потока значение tstate, которое не должно быть
NULL
. Если блокировка была создана, текущий поток не должен ее получить, в противном случае возникает взаимоблокировка.Примечание
Вызов этой функции из потока во время завершения выполнения приведет к завершению потока, даже если поток не был создан с помощью Python. Вы можете использовать
_Py_IsFinalizing()
илиsys.is_finalizing()
, чтобы проверить, находится ли интерпретатор в процессе завершения, прежде чем вызывать эту функцию, чтобы избежать нежелательного завершения.
-
PyThreadState *PyThreadState_Get()¶
- Part of the Стабильный ABI.
Возвращает текущее состояние потока. Глобальная блокировка интерпретатора должна быть сохранена. Когда текущее состояние потока равно
NULL
, это приводит к фатальной ошибке (так что вызывающей стороне не нужно проверять наличиеNULL
).
-
PyThreadState *PyThreadState_Swap(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть
NULL
. Глобальная блокировка интерпретатора должна удерживаться и не сниматься.
Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть . Глобальная блокировка интерпретатора должна удерживаться и не сниматься.
-
PyGILState_STATE PyGILState_Ensure()¶
- Part of the Стабильный ABI.
Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть
PyGILState_Release()
. ГлобальнаяPyGILState_Ensure()
блокировкаPyGILState_Release()
интерпретатора :macro:`Py_BEGIN_ALLOW_THREADS` должна :macro:`Py_END_ALLOW_THREADS` удерживаться и не сниматься.Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть
PyGILState_Ensure()
. ГлобальнаяPyGILState_Release()
блокировкаPyGILState_Ensure()
интерпретатораPyGILState_Release()
должна удерживаться и не сниматься.Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть . Глобальная блокировка интерпретатора должна удерживаться и не сниматься.
Примечание
Вызов этой функции из потока во время завершения выполнения приведет к завершению потока, даже если поток не был создан с помощью Python. Вы можете использовать
_Py_IsFinalizing()
илиsys.is_finalizing()
, чтобы проверить, находится ли интерпретатор в процессе завершения, прежде чем вызывать эту функцию, чтобы избежать нежелательного завершения.
-
void PyGILState_Release(PyGILState_STATE)¶
- Part of the Стабильный ABI.
Поменяйте текущее состояние потока на состояние потока, заданное аргументом tstate, которое может быть
PyGILState_Ensure()
. Глобальная блокировка интерпретатора должна удерживаться и не сниматься.Каждому вызову
PyGILState_Ensure()
должен соответствовать вызовPyGILState_Release()
в том же потоке.
-
PyThreadState *PyGILState_GetThisThreadState()¶
- Part of the Стабильный ABI.
Получаем текущее состояние потока для этого потока. Может возвращать
NULL
, если в текущем потоке не использовался GIL State API. Обратите внимание, что основной поток всегда имеет такое состояние потока, даже если в основном потоке не выполнялся автоматический вызов состояния потока. В основном это вспомогательная/диагностическая функция.
-
int PyGILState_Check()¶
Возвращает
1
, если текущий поток содержит GIL, и0
в противном случае. Эта функция может быть вызвана из любого потока в любое время. Только если состояние потока Python было инициализировано и в данный момент он содержит GIL, он вернет1
. В основном это вспомогательная/ диагностическая функция. Это может быть полезно, например, в контекстах обратного вызова или функциях выделения памяти, когда знание о том, что девушка заблокирована, может позволить вызывающему абоненту выполнять конфиденциальные действия или иным образом вести себя по-другому.Добавлено в версии 3.4.
Следующие макросы обычно используются без точки с запятой в конце; посмотрите пример использования в исходном коде Python.
-
Py_BEGIN_ALLOW_THREADS¶
- Part of the Стабильный ABI.
``{ PyThreadState *_save; _save = PyEval_SaveThread();``Следующие :macro:`Py_END_ALLOW_THREADS` макросы обычно используются без точки с запятой в конце; посмотрите пример использования в исходном коде Python.
-
Py_END_ALLOW_THREADS¶
- Part of the Стабильный ABI.
Этот макрос расширяется до
PyEval_RestoreThread(_save); }
. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросомPy_BEGIN_ALLOW_THREADS
. Дальнейшее обсуждение этого макроса смотрите выше.
-
Py_BLOCK_THREADS¶
- Part of the Стабильный ABI.
Этот макрос расширяется до
PyEval_RestoreThread(_save);
. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросомPy_END_ALLOW_THREADS
. Дальнейшее обсуждение этого макроса смотрите выше.
-
Py_UNBLOCK_THREADS¶
- Part of the Стабильный ABI.
Этот макрос расширяется до
_save = PyEval_SaveThread();
. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросомPy_BEGIN_ALLOW_THREADS
. Дальнейшее обсуждение этого макроса смотрите выше.
Этот макрос расширяется до . Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросом :c . Дальнейшее обсуждение этого макроса смотрите выше.¶
Этот макрос расширяется до Py_Initialize()
. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросом :c . Дальнейшее обсуждение этого макроса смотрите выше.
Изменено в версии 3.7: Этот макрос расширяется до Py_Initialize()
. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть сопоставлен с более ранним макросом GIL. Дальнейшее обсуждение этого макроса смотрите выше.
-
PyInterpreterState *PyInterpreterState_New()¶
- Part of the Стабильный ABI.
Создайте новый объект состояния интерпретатора. Глобальная блокировка интерпретатора не обязательно должна сохраняться, но может быть сохранена, если необходимо сериализовать вызовы этой функции.
Выдает auditing event
cpython.PyInterpreterState_New
без каких-либо аргументов.
-
void PyInterpreterState_Clear(PyInterpreterState *interp)¶
- Part of the Стабильный ABI.
Выдает без каких-либо аргументов.
Выдает auditing event
cpython.PyInterpreterState_Clear
без каких-либо аргументов.
-
void PyInterpreterState_Delete(PyInterpreterState *interp)¶
- Part of the Стабильный ABI.
Выдает
PyInterpreterState_Clear()
без каких-либо аргументов.
-
PyThreadState *PyThreadState_New(PyInterpreterState *interp)¶
- Part of the Стабильный ABI.
Создайте новый объект состояния потока, принадлежащий данному объекту интерпретатора. Глобальная блокировка интерпретатора не требуется, но может быть сохранена, если необходимо сериализовать вызовы этой функции.
-
void PyThreadState_Clear(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Сбросьте всю информацию в объекте состояния потока. Необходимо сохранить глобальную блокировку интерпретатора.
Изменено в версии 3.9: :member:`PyThreadState.on_delete`Сбросьте :func:`PyThreadState_Delete` всю информацию в объекте состояния потока. Необходимо сохранить глобальную блокировку интерпретатора.
-
void PyThreadState_Delete(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Уничтожьте объект состояния потока. Глобальная блокировка интерпретатора не требуется. Состояние потока должно быть сброшено с помощью предыдущего вызова
PyThreadState_Clear()
.
-
void PyThreadState_DeleteCurrent(void)¶
Уничтожьте объект состояния потока. Глобальная блокировка интерпретатора не требуется. Состояние потока должно быть сброшено с помощью предыдущего вызова
PyThreadState_Delete()
PyThreadState_Clear()
.
-
PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate)¶
- Part of the Стабильный ABI since version 3.10.
Уничтожьте объект состояния потока. Глобальная блокировка интерпретатора не требуется. Состояние потока должно быть сброшено с помощью предыдущего вызова :c .
Уничтожьте объект состояния потока. Глобальная блокировка интерпретатора не требуется. Состояние потока должно быть сброшено с помощью предыдущего вызова strong reference
NULL
.Смотрите также
PyEval_GetFrame()
.tstate не должно быть
NULL
.Добавлено в версии 3.9.
-
uint64_t PyThreadState_GetID(PyThreadState *tstate)¶
- Part of the Стабильный ABI since version 3.10.
tstate не должно быть .
tstate не должно быть
NULL
.Добавлено в версии 3.9.
-
PyInterpreterState *PyThreadState_GetInterpreter(PyThreadState *tstate)¶
- Part of the Стабильный ABI since version 3.10.
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()
.Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией
PyEval_SetTrace()
PyEval_SetProfile()
.Добавлено в версии 3.11.
-
PyInterpreterState *PyInterpreterState_Get(void)¶
- Part of the Стабильный ABI since version 3.9.
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c .
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c .
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c .
Добавлено в версии 3.9.
-
int64_t PyInterpreterState_GetID(PyInterpreterState *interp)¶
- Part of the Стабильный ABI since version 3.7.
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c``-1``.
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c .
Добавлено в версии 3.7.
-
PyObject *PyInterpreterState_GetDict(PyInterpreterState *interp)¶
- Part of the Стабильный ABI since version 3.8.
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c``NULL``.
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией
PyModule_GetState()
.Добавлено в версии 3.8.
-
typedef PyObject *(*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)¶
Возобновите трассировку и профилирование в состоянии потока Python tstate, приостановленном функцией :c .
Параметр throwflag используется методом генераторов
throw()
: если значение не равно нулю, обработайте текущее исключение.Изменено в версии 3.9: Параметр throwflag используется методом генераторов : если значение не равно нулю, обработайте текущее исключение.
Изменено в версии 3.11: Параметр frame изменен с
PyFrameObject*
на_PyInterpreterFrame*
.
-
_PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)¶
Параметр frame изменен с на .
Смотрите раздел PEP 523 «Добавление API для оценки фреймов в CPython».
Добавлено в версии 3.9.
-
void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame)¶
Установите функцию оценки кадра.
Смотрите раздел PEP 523 «Добавление API для оценки фреймов в CPython».
Добавлено в версии 3.9.
-
PyObject *PyThreadState_GetDict()¶
- Возвращаемое значение: Заимствованная ссылка. Part of the Стабильный ABI.
Возвращает словарь, в котором расширения могут хранить информацию о состоянии конкретного потока. Каждое расширение должно использовать уникальный ключ для хранения состояния в словаре. Эту функцию можно вызывать, когда текущее состояние потока недоступно. Если эта функция возвращает
NULL
, то исключение не было вызвано, и вызывающий объект должен предположить, что текущее состояние потока недоступно.
-
int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)¶
- Part of the Стабильный ABI.
Асинхронно генерировать исключение в потоке. Аргумент id - это идентификатор потока целевого потока; exc - это вызываемый объект исключения. Эта функция не крадет никаких ссылок на exc. Чтобы предотвратить неправильное использование, вы должны написать свое собственное расширение C для этого вызова. Должно вызываться с сохраненным GIL. Возвращает количество измененных состояний потока; обычно это единица, но будет равно нулю, если идентификатор потока не найден. Если значение exc равно
NULL
, ожидающее исключения исключение (если таковое имеется) для потока очищается. При этом исключений не возникает.Изменено в версии 3.7: Асинхронно генерировать исключение в потоке. Аргумент id - это идентификатор потока целевого потока; exc - это вызываемый объект исключения. Эта функция не крадет никаких ссылок на exc. Чтобы предотвратить неправильное использование, вы должны написать свое собственное расширение C для этого вызова. Должно вызываться с сохраненным GIL. Возвращает количество измененных состояний потока; обычно это единица, но будет равно нулю, если идентификатор потока не найден. Если значение exc равно :expr:`long`, ожидающее :expr:`unsigned long` исключения исключение (если таковое имеется) для потока очищается. При этом исключений не возникает.
-
void PyEval_AcquireThread(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Получите глобальную блокировку интерпретатора и установите текущее состояние потока в tstate, которое не должно быть
NULL
. Блокировка должна быть создана ранее. Если у этого потока уже есть блокировка, возникает взаимоблокировка.Примечание
Вызов этой функции из потока во время завершения выполнения приведет к завершению потока, даже если поток не был создан с помощью Python. Вы можете использовать
_Py_IsFinalizing()
илиsys.is_finalizing()
, чтобы проверить, находится ли интерпретатор в процессе завершения, прежде чем вызывать эту функцию, чтобы избежать нежелательного завершения.Изменено в версии 3.8: Получите глобальную блокировку интерпретатора и установите текущее состояние потока в tstate, которое не должно быть
PyEval_RestoreThread()
. БлокировкаPy_END_ALLOW_THREADS()
должнаPyGILState_Ensure()
быть создана ранее. Если у этого потока уже есть блокировка, возникает взаимоблокировка.PyEval_RestoreThread()
- это функция более высокого уровня, которая всегда доступна (даже если потоки не были инициализированы).
-
void PyEval_ReleaseThread(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Сбросьте текущее состояние потока на
NULL
и снимите глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и удерживаться текущим потоком. Аргумент tstate, который не должен бытьNULL
, используется только для проверки того, что он представляет текущее состояние потока - если это не так, сообщается о фатальной ошибке.PyEval_SaveThread()
- это функция более высокого уровня, которая всегда доступна (даже если потоки не были инициализированы).
-
void PyEval_AcquireLock()¶
- Part of the Стабильный ABI.
Получите глобальную блокировку интерпретатора. Блокировка, должно быть, была создана ранее. Если в этом потоке уже есть блокировка, возникает взаимоблокировка.
Не рекомендуется, начиная с версии 3.2: Эта функция не обновляет текущее состояние потока. Пожалуйста, используйте вместо этого
PyEval_RestoreThread()
илиPyEval_AcquireThread()
.Примечание
Вызов этой функции из потока во время завершения выполнения приведет к завершению потока, даже если поток не был создан с помощью Python. Вы можете использовать
_Py_IsFinalizing()
илиsys.is_finalizing()
, чтобы проверить, находится ли интерпретатор в процессе завершения, прежде чем вызывать эту функцию, чтобы избежать нежелательного завершения.Изменено в версии 3.8: Получите глобальную блокировку интерпретатора и установите текущее состояние потока в tstate, которое не должно быть
PyEval_RestoreThread()
. БлокировкаPy_END_ALLOW_THREADS()
должнаPyGILState_Ensure()
быть создана ранее. Если у этого потока уже есть блокировка, возникает взаимоблокировка.
-
void PyEval_ReleaseLock()¶
- Part of the Стабильный ABI.
Снимите глобальную блокировку интерпретатора. Блокировка, должно быть, была создана ранее.
Не рекомендуется, начиная с версии 3.2: Эта функция не обновляет текущее состояние потока. Пожалуйста, используйте вместо этого
PyEval_SaveThread()
илиPyEval_ReleaseThread()
.
Дополнительный переводчик¶
Хотя в большинстве случаев вы внедряете только один интерпретатор Python, бывают случаи, когда вам нужно создать несколько независимых интерпретаторов в одном процессе и, возможно, даже в одном потоке. Вспомогательные интерпретаторы позволяют это сделать.
«Основной» интерпретатор создается первым при инициализации среды выполнения. Обычно это единственный интерпретатор Python в процессе. В отличие от вспомогательных интерпретаторов, основной интерпретатор выполняет уникальные глобальные функции, такие как обработка сигналов. Она также отвечает за выполнение во время инициализации среды выполнения и обычно является активным интерпретатором во время завершения среды выполнения. Функция PyInterpreterState_Main()
возвращает указатель на свое состояние.
Вы можете переключаться между вспомогательными интерпретаторами, используя функцию PyThreadState_Swap()
. Вы можете создавать и уничтожать их, используя следующие функции:
-
PyThreadState *Py_NewInterpreter()¶
- Part of the Стабильный ABI.
Создайте новый вспомогательный интерпретатор. Это (почти) полностью отдельная среда для выполнения кода на Python. В частности, новый интерпретатор имеет отдельные, независимые версии всех импортированных модулей, включая основные модули
builtins
,__main__
иsys
. Таблица загруженных модулей (sys.modules
) и путь поиска модуля (sys.path
) также разделены. В новой среде нет переменнойsys.argv
. В нем появились новые стандартные файловые объекты потока ввода-выводаsys.stdin
,sys.stdout
иsys.stderr
(однако они ссылаются на одни и те же базовые файловые дескрипторы).Создайте новый вспомогательный интерпретатор. Это (почти) полностью отдельная среда для выполнения кода на Python. В частности, новый интерпретатор имеет отдельные, независимые версии всех импортированных модулей, включая основные модули
NULL
, и . Таблица загруженных модулей ( ) и путь поиска модуля ( ) также разделены. В новой среде нет переменной . В нем появились новые стандартные файловые объекты потока ввода-вывода , и (однако они ссылаются на одни и те же базовые файловые дескрипторы).Дополнительные модули распределяются между (вспомогательными) переводчиками следующим образом:
Для модулей, использующих многоэтапную инициализацию, например : c:func:PyModule_FromDefAndSpec, для каждого интерпретатора создается и инициализируется отдельный объект модуля. Только статические и глобальные переменные уровня C являются общими для этих объектов модуля.
Для модулей, использующих однофазную инициализацию, например
PyModule_Create()
, при первом импорте определенного расширения оно инициализируется обычным образом, и (небольшая) копия словаря этого модуля сохраняется. Когда то же самое расширение импортируется другим (вспомогательным) интерпретатором, инициализируется новый модуль и заполняется содержимым этой копии; функция расширенияinit
не вызывается. Таким образом, объекты в словаре модуля становятся общими для всех (под) интерпретаторов, что может привести к нежелательному поведению (см. Bugs and caveats ниже).Для модулей, использующих однофазную инициализацию, например
Py_FinalizeEx()
, при первом импорте определенного расширения оно инициализируется обычным образом, и (небольшая) копия словаря этого модуля сохраняется. Когда то же самое расширение импортируется другим (вспомогательным) интерпретатором, инициализируется новый модуль и заполняется содержимым этой копии; функция расширенияPy_Initialize()
не вызывается. Таким образом, объекты в словаре модуля становятся общими для всех (под) интерпретаторов, что может привести к нежелательному поведению (см.initmodule
ниже).
-
void Py_EndInterpreter(PyThreadState *tstate)¶
- Part of the Стабильный ABI.
Уничтожьте (вспомогательный) интерпретатор, представленный данным состоянием потока. Данное состояние потока должно быть текущим состоянием потока. Смотрите обсуждение состояний потока ниже. Когда вызов возвращается, текущее состояние потока равно
NULL
. Все состояния потока, связанные с этим интерпретатором, уничтожаются. (Глобальная блокировка интерпретатора должна быть установлена перед вызовом этой функции и по-прежнему сохраняется при ее возврате.)Py_FinalizeEx()
уничтожит все вспомогательные интерпретаторы, которые не были явно уничтожены в этот момент.
Ошибки и предостережения¶
Поскольку вспомогательные интерпретаторы (и основной интерпретатор) являются частью одного и того же процесса, изоляция между ними не идеальна - например, при использовании низкоуровневых файловых операций, таких как os.close()
, они могут (случайно или злонамеренно) влиять на открытые файлы друг друга. Из-за того, что расширения совместно используются (под) интерпретаторами, некоторые расширения могут работать неправильно; это особенно вероятно при использовании однофазной инициализации или (статических) глобальных переменных. Можно вставлять объекты, созданные в одном субинтерпретаторе, в пространство имен другого (суб-)интерпретатора; по возможности, этого следует избегать.
Следует проявлять особую осторожность, чтобы избежать совместного использования пользовательских функций, методов, экземпляров или классов между субинтерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут повлиять на неправильный словарь загруженных модулей (субинтерпретатора). Не менее важно избегать совместного использования объектов, из которых все вышеперечисленное доступно.
Также обратите внимание, что объединение этой функциональности с PyGILState_*
API-интерфейсами является сложной задачей, поскольку эти API-интерфейсы предполагают биекцию между состояниями потоков Python и потоками на уровне операционной системы, что противоречит предположению о наличии вспомогательных интерпретаторов. Настоятельно рекомендуется не переключать вспомогательные интерпретаторы между парой совпадающих вызовов PyGILState_Ensure()
и PyGILState_Release()
. Кроме того, расширения (такие как ctypes
), использующие эти API для вызова кода Python из потоков, созданных не на Python, вероятно, будут нарушены при использовании вспомогательных интерпретаторов.
Также обратите внимание, что объединение этой функциональности с API-интерфейсами является сложной задачей, поскольку эти API-интерфейсы предполагают биекцию между состояниями потоков Python и потоками на уровне операционной системы, что противоречит предположению о наличии вспомогательных интерпретаторов. Настоятельно рекомендуется не переключать вспомогательные интерпретаторы между парой совпадающих вызовов :c и :c . Кроме того, расширения (такие как ), использующие эти API для вызова кода Python из потоков, созданных не на Python, вероятно, будут нарушены при использовании вспомогательных интерпретаторов.¶
Предусмотрен механизм для отправки асинхронных уведомлений в основной поток интерпретатора. Эти уведомления принимают форму указателя на функцию и аргумента void-указателя.
-
int Py_AddPendingCall(int (*func)(void*), void *arg)¶
- Part of the Стабильный ABI.
Запланируйте вызов функции из основного потока интерпретатора. В случае успеха возвращается
0
и func ставится в очередь для вызова в основном потоке. В случае неудачи возвращается-1
без установки какого-либо исключения.После успешной постановки в очередь функция func будет * в конечном итоге* вызвана из основного потока интерпретатора с аргументом arg. Она будет вызываться асинхронно по отношению к обычно выполняемому коду на Python, но при соблюдении обоих этих условий:
на границе bytecode;
с основным потоком, содержащим global interpreter lock (таким образом, func может использовать полный C API).
функция должна возвращать
0
в случае успеха или-1
в случае сбоя с установленным исключением. функция не будет прервана для выполнения другого асинхронного уведомления рекурсивно, но она все равно может быть прервана для переключения потоков, если глобальная блокировка интерпретатора снята.Для запуска этой функции не требуется текущее состояние потока, и ей не требуется глобальная блокировка интерпретатора.
Чтобы вызвать эту функцию во вспомогательном интерпретаторе, вызывающий объект должен содержать GIL. В противном случае вызов функции func может быть запланирован не из того интерпретатора.
Предупреждение
Это низкоуровневая функция, полезная только в особых случаях. Нет гарантии, что функция func будет вызвана как можно быстрее. Если основной поток занят выполнением системного вызова, функция func не будет вызвана до того, как системный вызов вернется. Эта функция, как правило, не подходит для вызова кода на Python из произвольных потоков C. Вместо этого используйте PyGILState API.
Добавлено в версии 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
Всегда
Py_None
.Информация об исключении, возвращаемая
sys.exc_info()
.Всегда
Py_None
.Значение, возвращаемое вызывающей стороне, или
NULL
, если оно вызвано исключением.Вызываемый функциональный объект.
Вызываемый функциональный объект.
Вызываемый функциональный объект.
Всегда
Py_None
.
-
int PyTrace_CALL¶
Значение параметра what для функции a
Py_tracefunc
, когда сообщается о новом вызове функции или метода или о новой записи в генераторе. Обратите внимание, что о создании итератора для функции-генератора не сообщается, поскольку в соответствующем фрейме нет передачи управления байт-коду Python.
-
int PyTrace_EXCEPTION¶
Значение параметра what для функции a
Py_tracefunc
при возникновении исключения. Функция обратного вызова вызывается с этим значением для what when после обработки любого байт-кода, после чего исключение устанавливается в пределах выполняемого фрейма. Результатом этого является то, что, поскольку распространение исключения приводит к раскручиванию стека 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
. Если функции profile необходимо поддерживать состояние, использование другого значения для obj для каждого потока обеспечивает удобное и потокобезопасное место для его хранения. Функция профиля вызывается для всех отслеживаемых событий, за исключениемPyTrace_LINE
PyTrace_OPCODE
иPyTrace_EXCEPTION
.Смотрите также функцию
sys.setprofile()
.Вызывающий должен удерживать GIL.
-
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.
Расширенная поддержка отладчика¶
Эти функции предназначены только для использования продвинутыми средствами отладки.
-
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 обеспечивает низкоуровневую поддержку thread-local storage (TLS), которая обертывает базовую реализацию native TLS для поддержки API thread-local storage на уровне Python (threading.local
). API-интерфейсы CPython на уровне C аналогичны тем, которые предлагаются pthreads и Windows: используйте ключ потока и функции для привязки значения void* для каждого потока.
GIL не нужно удерживать при вызове этих функций; они обеспечивают свою собственную блокировку.
Обратите внимание, что Python.h
не содержит объявления API-интерфейсов TLS, вам необходимо включить pythread.h
, чтобы использовать локальное хранилище потоков.
Примечание
Ни одна из этих функций API не управляет памятью от имени значений void*. Вам необходимо самостоятельно выделять и освобождать их. Если значения void* равны PyObject*, эти функции также не выполняют операции повторного подсчета для них.
API хранилища для конкретных потоков (TSS)¶
TSS API вводится вместо существующего TLS API в интерпретаторе CPython. В этом API используется новый тип : c:type: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()¶
- Part of the Стабильный ABI since version 3.7.
Возвращает значение, которое находится в том же состоянии, что и значение, инициализированное с помощью
Py_tss_NEEDS_INIT
илиNULL
в случае сбоя динамического распределения.
-
void PyThread_tss_free(Py_tss_t *key)¶
- Part of the Стабильный ABI since version 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)¶
- Part of the Стабильный ABI since version 3.7.
Возвращает ненулевое значение, если заданный
Py_tss_t
был инициализированPyThread_tss_create()
.
-
int PyThread_tss_create(Py_tss_t *key)¶
- Part of the Стабильный ABI since version 3.7.
Возвращает нулевое значение при успешной инициализации ключа DSS. Поведение не определено, если значение, на которое указывает аргумент key, не инициализировано
Py_tss_NEEDS_INIT
. Эта функция может вызываться повторно по одному и тому же ключу - вызов ее по уже инициализированному ключу бесполезен и немедленно возвращает результат успеха.
-
void PyThread_tss_delete(Py_tss_t *key)¶
- Part of the Стабильный ABI since version 3.7.
Уничтожьте его ключ, чтобы забыть значения, связанные с ключом во всех потоках, и измените состояние инициализации ключа на неинициализированное. Уничтоженный ключ можно снова инициализировать с помощью:c:func:PyThread_tss_create. Эта функция может быть вызвана повторно для одной и той же клавиши - вызывать ее для уже уничтоженной клавиши бесполезно.
-
int PyThread_tss_set(Py_tss_t *key, void *value)¶
- Part of the Стабильный ABI since version 3.7.
Возвращает нулевое значение, указывающее на успешное сопоставление значения void* с ключом TSS в текущем потоке. Каждый поток имеет отдельное отображение ключа на значение void*.
-
void *PyThread_tss_get(Py_tss_t *key)¶
- Part of the Стабильный ABI since version 3.7.
Возвращает значение void*, связанное с ключом TSS в текущем потоке. Возвращает значение
NULL
, если в текущем потоке с ключом не связано никакое значение.
API локального хранилища потоков (TLS)¶
Не рекомендуется, начиная с версии 3.7: Этот API заменен на Thread Specific Storage (TSS) API.
Примечание
Эта версия API не поддерживает платформы, где собственный ключ TLS определен таким образом, что его невозможно безопасно привести к int
. На таких платформах PyThread_create_key()
немедленно возвращается со статусом сбоя, а все остальные функции TLS на таких платформах не работают.
Из-за проблемы совместимости, отмеченной выше, эта версия API не должна использоваться в новом коде.
-
int PyThread_create_key()¶
- Part of the Стабильный ABI.
-
void PyThread_delete_key(int key)¶
- Part of the Стабильный ABI.
-
int PyThread_set_key_value(int key, void *value)¶
- Part of the Стабильный ABI.
-
void *PyThread_get_key_value(int key)¶
- Part of the Стабильный ABI.
-
void PyThread_delete_key_value(int key)¶
- Part of the Стабильный ABI.
-
void PyThread_ReInitTLS()¶
- Part of the Стабильный ABI.