init.md
1> **Источник:** https://python-all.ru/3.10/c-api/init.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Инициализация, финализация и потоки89См. также [Конфигурация инициализации Python](https://python-all.ru/3.10/c-api/init_config.html#init-config).1011## Перед инициализацией Python1213В приложении, внедряющем Python, функция [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize) должна быть вызвана до использования любых других функций Python/C API; за исключением нескольких функций и [глобальных переменных конфигурации](https://python-all.ru/3.10/c-api/init.html#global-conf-vars).1415Следующие функции можно безопасно вызывать до инициализации Python:1617- Функции конфигурации:1819 - [`PyImport_AppendInittab()`](https://python-all.ru/3.10/c-api/import.html#c.PyImport_AppendInittab)20 - [`PyImport_ExtendInittab()`](https://python-all.ru/3.10/c-api/import.html#c.PyImport_ExtendInittab)21 - `PyInitFrozenExtensions()`22 - [`PyMem_SetAllocator()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_SetAllocator)23 - [`PyMem_SetupDebugHooks()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_SetupDebugHooks)24 - [`PyObject_SetArenaAllocator()`](https://python-all.ru/3.10/c-api/memory.html#c.PyObject_SetArenaAllocator)25 - [`Py_SetPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetPath)26 - [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName)27 - [`Py_SetPythonHome()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetPythonHome)28 - [`Py_SetStandardStreamEncoding()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetStandardStreamEncoding)29 - [`PySys_AddWarnOption()`](https://python-all.ru/3.10/c-api/sys.html#c.PySys_AddWarnOption)30 - [`PySys_AddXOption()`](https://python-all.ru/3.10/c-api/sys.html#c.PySys_AddXOption)31 - [`PySys_ResetWarnOptions()`](https://python-all.ru/3.10/c-api/sys.html#c.PySys_ResetWarnOptions)32- Информационные функции:3334 - [`Py_IsInitialized()`](https://python-all.ru/3.10/c-api/init.html#c.Py_IsInitialized)35 - [`PyMem_GetAllocator()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_GetAllocator)36 - [`PyObject_GetArenaAllocator()`](https://python-all.ru/3.10/c-api/memory.html#c.PyObject_GetArenaAllocator)37 - [`Py_GetBuildInfo()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetBuildInfo)38 - [`Py_GetCompiler()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetCompiler)39 - [`Py_GetCopyright()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetCopyright)40 - [`Py_GetPlatform()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPlatform)41 - [`Py_GetVersion()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetVersion)42- Утилиты:4344 - [`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale)45- Распределители памяти:4647 - [`PyMem_RawMalloc()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_RawMalloc)48 - [`PyMem_RawRealloc()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_RawRealloc)49 - [`PyMem_RawCalloc()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_RawCalloc)50 - [`PyMem_RawFree()`](https://python-all.ru/3.10/c-api/memory.html#c.PyMem_RawFree)5152> **Примечание**53>54> Следующие функции **нельзя вызывать** до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize): [`Py_EncodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_EncodeLocale), [`Py_GetPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPath), [`Py_GetPrefix()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPrefix), [`Py_GetExecPrefix()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetExecPrefix), [`Py_GetProgramFullPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetProgramFullPath), [`Py_GetPythonHome()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPythonHome), [`Py_GetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetProgramName) и [`PyEval_InitThreads()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_InitThreads).5556## Глобальные переменные конфигурации5758В Python есть переменные глобальной конфигурации, управляющие различными возможностями и настройками. По умолчанию эти флаги задаются [параметрами командной строки](https://python-all.ru/3.10/using/cmdline.html#using-on-interface-options).5960Когда флаг устанавливается через параметр, значение флага равно количеству раз, которое этот параметр был указан. Например, `-b` устанавливает [`Py_BytesWarningFlag`](https://python-all.ru/3.10/c-api/init.html#c.Py_BytesWarningFlag) в 1, а `-bb` устанавливает [`Py_BytesWarningFlag`](https://python-all.ru/3.10/c-api/init.html#c.Py_BytesWarningFlag) в 2.6162#### `int Py_BytesWarningFlag`6364Выдавать предупреждение при сравнении [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.10/library/stdtypes.html#bytearray) с [`str`](https://python-all.ru/3.10/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.10/library/stdtypes.html#bytes) с [`int`](https://python-all.ru/3.10/library/functions.html#int). Если значение больше или равно `2`, выдавать ошибку.6566Устанавливается опцией [`-b`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-b).6768#### `int Py_DebugFlag`6970Включает отладочный вывод парсера (только для экспертов, зависит от опций компиляции).7172Устанавливается опцией [`-d`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-d) и переменной окружения [`PYTHONDEBUG`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONDEBUG).7374#### `int Py_DontWriteBytecodeFlag`7576Если установлено ненулевое значение, Python не будет пытаться записывать файлы `.pyc` при импорте исходных модулей.7778Устанавливается опцией [`-B`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-B) и переменной окружения [`PYTHONDONTWRITEBYTECODE`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE).7980#### `int Py_FrozenFlag`8182Подавляет сообщения об ошибках при вычислении пути поиска модулей в [`Py_GetPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPath).8384Внутренний флаг, используемый программами `_freeze_importlib` и `frozenmain`.8586#### `int Py_HashRandomizationFlag`8788Устанавливается в `1`, если переменная окружения [`PYTHONHASHSEED`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONHASHSEED) установлена в непустую строку.8990Если флаг ненулевой, читает переменную окружения [`PYTHONHASHSEED`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONHASHSEED) для инициализации секретного начального значения хеша.9192#### `int Py_IgnoreEnvironmentFlag`9394Игнорировать все переменные окружения `PYTHON*`, например [`PYTHONPATH`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONPATH) и [`PYTHONHOME`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONHOME), которые могут быть установлены.9596Устанавливается параметрами [`-E`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-E) и [`-I`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-I).9798#### `int Py_InspectFlag`99100Если скрипт передан первым аргументом или используется параметр [`-c`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-c), после выполнения скрипта или команды перейти в интерактивный режим, даже если [`sys.stdin`](https://python-all.ru/3.10/library/sys.html#sys.stdin) не является терминалом.101102Устанавливается опцией [`-i`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-i) и переменной окружения [`PYTHONINSPECT`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONINSPECT).103104#### `int Py_InteractiveFlag`105106Устанавливается опцией [`-i`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-i).107108#### `int Py_IsolatedFlag`109110Запуск Python в изолированном режиме. В изолированном режиме [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) не содержит ни каталог скрипта, ни каталог site-packages пользователя.111112Устанавливается опцией [`-I`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-I).113114Новое в версии 3.4.115116#### `int Py_LegacyWindowsFSEncodingFlag`117118Если флаг ненулевой, используется кодировка `mbcs` с обработчиком ошибок `replace` вместо кодировки UTF-8 с обработчиком ошибок `surrogatepass` для [кодировки файловой системы и обработчика ошибок](https://python-all.ru/3.10/glossary.html#term-filesystem-encoding-and-error-handler).119120Устанавливается в `1`, если переменная окружения [`PYTHONLEGACYWINDOWSFSENCODING`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONLEGACYWINDOWSFSENCODING) установлена в непустую строку.121122См. [**PEP 529**](https://python-all.ru/3.10/c-api/init.html) для подробностей.123124[Доступность](https://python-all.ru/3.10/library/intro.html#availability): Windows.125126#### `int Py_LegacyWindowsStdioFlag`127128Если флаг ненулевой, используется [`io.FileIO`](https://python-all.ru/3.10/library/io.html#io.FileIO) вместо `WindowsConsoleIO` для [`sys`](https://python-all.ru/3.10/library/sys.html#module-sys) стандартных потоков.129130Устанавливается в `1`, если переменная окружения [`PYTHONLEGACYWINDOWSSTDIO`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONLEGACYWINDOWSSTDIO) установлена в непустую строку.131132См. [**PEP 528**](https://python-all.ru/3.10/c-api/init.html) для подробностей.133134[Доступность](https://python-all.ru/3.10/library/intro.html#availability): Windows.135136#### `int Py_NoSiteFlag`137138Отключает импорт модуля [`site`](https://python-all.ru/3.10/library/site.html#module-site) и связанные с ним site-зависимые манипуляции с [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path). Также отключает эти манипуляции, если [`site`](https://python-all.ru/3.10/library/site.html#module-site) явно импортирован позже (для их выполнения следует вызвать [`site.main()`](https://python-all.ru/3.10/library/site.html#site.main)).139140Устанавливается опцией [`-S`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-S).141142#### `int Py_NoUserSiteDirectory`143144Не добавляет [`user site-packages directory`](https://python-all.ru/3.10/library/site.html#site.USER_SITE) в [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path).145146Устанавливается параметрами [`-s`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-s) и [`-I`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-I), а также переменной окружения [`PYTHONNOUSERSITE`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONNOUSERSITE).147148#### `int Py_OptimizeFlag`149150Устанавливается опцией [`-O`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-O) и переменной окружения [`PYTHONOPTIMIZE`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONOPTIMIZE).151152#### `int Py_QuietFlag`153154Не выводить сообщения об авторских правах и версии, даже в интерактивном режиме.155156Устанавливается опцией [`-q`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-q).157158Новое в версии 3.2.159160#### `int Py_UnbufferedStdioFlag`161162Принудительно отключает буферизацию потоков stdout и stderr.163164Устанавливается опцией [`-u`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-u) и переменной окружения [`PYTHONUNBUFFERED`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONUNBUFFERED).165166#### `int Py_VerboseFlag`167168Выводит сообщение каждый раз при инициализации модуля, указывая, откуда он загружается (имя файла или встроенный модуль). Если значение больше или равно `2`, выводит сообщение для каждого файла, который проверяется при поиске модуля. Также предоставляет информацию об очистке модулей при завершении работы.169170Устанавливается опцией [`-v`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-1) и переменной окружения [`PYTHONVERBOSE`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONVERBOSE).171172## Инициализация и завершение работы интерпретатора173174#### `void Py_Initialize()`175176*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*177178Инициализирует интерпретатор Python. В приложении, встраивающем Python, эту функцию следует вызывать до использования любых других функций Python/C API; за несколькими исключениями обращайтесь к [Before Python Initialization](https://python-all.ru/3.10/c-api/init.html#pre-init-safe).179180Эта функция инициализирует таблицу загруженных модулей (`sys.modules`) и создает фундаментальные модули [`builtins`](https://python-all.ru/3.10/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.10/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.10/library/sys.html#module-sys). Она также инициализирует путь поиска модулей (`sys.path`). Она не устанавливает `sys.argv`; для этого используйте [`PySys_SetArgvEx()`](https://python-all.ru/3.10/c-api/init.html#c.PySys_SetArgvEx). При повторном вызове (без предварительного вызова [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx)) ничего не происходит. Возвращаемого значения нет; если инициализация не удалась, это фатальная ошибка.181182> **Примечание**183>184> В Windows изменяет режим консоли с `O_TEXT` на `O_BINARY`, что также повлияет на использование консоли из других приложений на C Runtime.185186#### `void Py_InitializeEx(int initsigs)`187188*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*189190Эта функция работает как [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), если *initsigs* равно `1`. Если *initsigs* равно `0`, она пропускает регистрацию обработчиков сигналов при инициализации, что может быть полезно при встраивании Python.191192#### `int Py_IsInitialized()`193194*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*195196Возвращает true (ненулевое значение), если интерпретатор Python был инициализирован, и false (ноль), если нет. После вызова [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx) функция возвращает false до тех пор, пока не будет снова вызвана [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).197198#### `int Py_FinalizeEx()`199200*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.6.*201202Отменяет все инициализации, выполненные [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize) и последующим использованием функций Python/C API, и уничтожает все под-интерпретаторы (см. [`Py_NewInterpreter()`](https://python-all.ru/3.10/c-api/init.html#c.Py_NewInterpreter) ниже), которые были созданы и ещё не уничтожены с последнего вызова [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize). В идеале это освобождает всю память, выделенную интерпретатором Python. При повторном вызове (без предварительного вызова [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize)) ничего не делает. Обычно возвращаемое значение – `0`. Если во время завершения произошли ошибки (при сбросе буферизованных данных), возвращается `-1`.203204Эта функция предусмотрена по ряду причин. Встраивающее приложение может захотеть перезапустить Python без перезапуска самого приложения. Приложение, загрузившее интерпретатор Python из динамически загружаемой библиотеки (или DLL), может захотеть освободить всю память, выделенную Python, перед выгрузкой DLL. В процессе поиска утечек памяти в приложении разработчик может захотеть освободить всю память, выделенную Python, перед выходом из приложения.205206**Ошибки и предостережения:** Уничтожение модулей и объектов в модулях происходит в случайном порядке; из-за этого деструкторы (методы `__del__()`) могут давать сбой, если они зависят от других объектов (даже функций) или модулей. Динамически загруженные модули расширений, загруженные Python, не выгружаются. Небольшие объёмы памяти, выделенные интерпретатором Python, могут не освобождаться (если вы обнаружили утечку, сообщите о ней). Память, связанная циклическими ссылками между объектами, не освобождается. Некоторая память, выделенная модулями расширений, может не освобождаться. Некоторые расширения могут работать неправильно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение вызывает [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize) и [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx) более одного раза.207208Возбуждает [событие аудита](https://python-all.ru/3.10/library/sys.html#auditing) `cpython._PySys_ClearAuditHooks` без аргументов.209210Новое в версии 3.6.211212#### `void Py_Finalize()`213214*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*215216Это обратно совместимая версия [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx), которая игнорирует возвращаемое значение.217218## Общепроцессные параметры219220#### `int Py_SetStandardStreamEncoding(const char *encoding, const char *errors)`221222Эта функция должна вызываться до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), если она вообще вызывается. Она указывает, какую кодировку и обработку ошибок использовать для стандартного ввода-вывода, с теми же значениями, что и в [`str.encode()`](https://python-all.ru/3.10/library/stdtypes.html#str.encode).223224Она переопределяет значения [`PYTHONIOENCODING`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONIOENCODING) и позволяет встраивать код для управления кодировкой ввода-вывода, когда переменная окружения не работает.225226*encoding* и/или *errors* могут быть `NULL`, чтобы использовать [`PYTHONIOENCODING`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONIOENCODING) и/или значения по умолчанию (в зависимости от других настроек).227228Обратите внимание, что [`sys.stderr`](https://python-all.ru/3.10/library/sys.html#sys.stderr) всегда использует обработчик ошибок «backslashreplace», независимо от этой (или любой другой) настройки.229230Если вызывается [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx), эту функцию потребуется вызвать снова, чтобы повлиять на последующие вызовы [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).231232Возвращает `0` в случае успеха, ненулевое значение при ошибке (например, при вызове после того, как интерпретатор уже был инициализирован).233234Новое в версии 3.4.235236#### `void Py_SetProgramName(const wchar_t *name)`237238*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*239240Эту функцию следует вызвать до первого вызова [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), если она вообще вызывается. Она сообщает интерпретатору значение аргумента `argv[0]` функции `main()` программы (преобразованное в широкие символы). Это используется [`Py_GetPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPath) и некоторыми другими функциями ниже для поиска библиотек времени выполнения Python относительно исполняемого файла интерпретатора. Значение по умолчанию – `'python'`. Аргумент должен указывать на строку широких символов, завершающуюся нулём, в статической памяти, содержимое которой не изменится за время выполнения программы. Никакой код в интерпретаторе Python не изменит содержимое этой памяти.241242[`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale) используется для декодирования строки байтов и получения `wchar_*` строки.243244#### `wchar *Py_GetProgramName()`245246*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*247248Возвращает имя программы, установленное с помощью [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName), или значение по умолчанию. Возвращаемая строка указывает на статическую память; вызывающий не должен изменять её значение.249250Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.251252Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).253254#### `wchar_t *Py_GetPrefix()`255256*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*257258Возвращает *префикс* для установленных платформонезависимых файлов. Он определяется по ряду сложных правил из имени программы, установленного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName), и некоторых переменных окружения; например, если имя программы – `'/usr/local/bin/python'`, префикс – `'/usr/local'`. Возвращаемая строка указывает на статическую память; вызывающий не должен изменять её значение. Это соответствует переменной **prefix** в корневом `Makefile` и аргументу [`--prefix`](https://python-all.ru/3.10/using/configure.html#cmdoption-prefix) сценария **configure** во время сборки. Значение доступно в коде Python как `sys.prefix`. Полезен только в Unix. Смотрите также следующую функцию.259260Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.261262Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).263264#### `wchar_t *Py_GetExecPrefix()`265266*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*267268Возвращает *exec-prefix* для установленных *зависящих от платформы* файлов. Это значение вычисляется по ряду сложных правил на основе имени программы, заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName), и некоторых переменных окружения; например, если имя программы – `'/usr/local/bin/python'`, то exec-prefix – `'/usr/local'`. Возвращаемая строка указывает на статическую память; вызывающий не должен изменять её значение. Это соответствует переменной **exec\_prefix** в верхнеуровневом `Makefile` и аргументу `--exec-prefix` сценария **configure** во время сборки. Значение доступно коду Python как `sys.exec_prefix`. Это имеет смысл только в Unix.269270Контекст: exec-prefix отличается от префикса (prefix), когда зависящие от платформы файлы (например, исполняемые файлы и динамические библиотеки) устанавливаются в другое дерево каталогов. В типичной установке платформенно-зависимые файлы могут быть установлены в поддерево `/usr/local/plat`, а платформенно-независимые – в `/usr/local`.271272Вообще говоря, платформа – это комбинация семейств аппаратного и программного обеспечения; например, машины Sparc под управлением ОС Solaris 2.x считаются одной платформой, машины Intel под Solaris 2.x – другой, а машины Intel под Linux – третьей. Разные основные версии одной и той же ОС обычно также образуют разные платформы. Операционные системы, отличные от Unix, – это отдельная история; стратегии установки на этих системах настолько различаются, что префикс и exec-prefix не имеют смысла и устанавливаются в пустую строку. Обратите внимание: скомпилированные файлы байт-кода Python не зависят от платформы (но не от версии Python, под которой они были скомпилированы!).273274Системные администраторы знают, как настроить программы **mount** или **automount** для совместного использования `/usr/local` между платформами, при этом `/usr/local/plat` будет отдельной файловой системой для каждой платформы.275276Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.277278Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).279280#### `wchar_t *Py_GetProgramFullPath()`281282*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*283284Возвращает полное имя программы исполняемого файла Python; оно вычисляется как побочный эффект при получении пути поиска модулей по умолчанию из имени программы (заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName) выше). Возвращаемая строка указывает на статическую память; вызывающий не должен изменять её значение. Значение доступно коду Python как `sys.executable`.285286Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.287288Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).289290#### `wchar_t *Py_GetPath()`291292*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*293294Возвращает путь поиска модулей по умолчанию; он вычисляется из имени программы (заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetProgramName) выше) и некоторых переменных окружения. Возвращаемая строка состоит из последовательности имён каталогов, разделённых символом-разделителем, зависящим от платформы. На Unix и macOS символом-разделителем является `':'`, на Windows – `';'`. Возвращаемая строка указывает на статическую память; вызывающий не должен изменять её значение. Список [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) инициализируется этим значением при запуске интерпретатора; он может быть (и обычно) изменён позднее для изменения пути поиска модулей.295296Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.297298Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).299300#### `void Py_SetPath(const wchar_t*)`301302*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*303304Устанавливает путь поиска модулей по умолчанию. Если эта функция вызывается до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), то [`Py_GetPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetPath) не будет пытаться вычислить путь по умолчанию, а использует предоставленный. Это полезно, если Python встраивается в приложение, которое точно знает расположение всех модулей. Компоненты пути должны разделяться символом-разделителем, зависящим от платформы: `':'` на Unix и macOS, `';'` на Windows.305306Это также приводит к тому, что [`sys.executable`](https://python-all.ru/3.10/library/sys.html#sys.executable) устанавливается в полный путь программы (см. [`Py_GetProgramFullPath()`](https://python-all.ru/3.10/c-api/init.html#c.Py_GetProgramFullPath)), а [`sys.prefix`](https://python-all.ru/3.10/library/sys.html#sys.prefix) и [`sys.exec_prefix`](https://python-all.ru/3.10/library/sys.html#sys.exec_prefix) становятся пустыми. Вызывающий может изменить их при необходимости после вызова [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).307308Используйте [`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale) для декодирования строки байтов, чтобы получить строку `wchar_*`.309310Аргумент path копируется внутри, поэтому вызывающий может освободить его после завершения вызова.311312Изменено в версии 3.8: Теперь для [`sys.executable`](https://python-all.ru/3.10/library/sys.html#sys.executable) используется полный путь программы, а не имя программы.313314#### `const char *Py_GetVersion()`315316*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*317318Возвращает версию данного интерпретатора Python. Это строка, которая выглядит примерно так:319320```c321"3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"322```323324Первое слово (до первого пробела) – это текущая версия Python; первые символы – это мажорная и минорная версии, разделённые точкой. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как [`sys.version`](https://python-all.ru/3.10/library/sys.html#sys.version).325326#### `const char *Py_GetPlatform()`327328*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*329330Возвращает идентификатор платформы для текущей платформы. В Unix он формируется из «официального» имени операционной системы, преобразованного в нижний регистр, за которым следует номер основной ревизии; например, для Solaris 2.x, также известного как SunOS 5.x, значение – `'sunos5'`. В macOS – `'darwin'`. В Windows – `'win'`. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно в коде Python как `sys.platform`.331332#### `const char *Py_GetCopyright()`333334*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*335336Возвращает официальную строку авторских прав для текущей версии Python, например337338`'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`339340Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно в коде Python как `sys.copyright`.341342#### `const char *Py_GetCompiler()`343344*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*345346Возвращает указание компилятора, использованного для сборки текущей версии Python, в квадратных скобках, например:347348```c349"[GCC 2.7.2.2]"350```351352Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно коду Python как часть переменной `sys.version`.353354#### `const char *Py_GetBuildInfo()`355356*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*357358Возвращает информацию о номере сборки, дате и времени сборки текущего экземпляра интерпретатора Python, например359360```c361"#67, Aug 1 1997, 22:34:28"362```363364Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно коду Python как часть переменной `sys.version`.365366#### `void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)`367368*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*369370Устанавливает [`sys.argv`](https://python-all.ru/3.10/library/sys.html#sys.argv) на основе *argc* и *argv*. Эти параметры похожи на передаваемые функции `main()` программы, с тем отличием, что первый элемент должен указывать на исполняемый файл сценария, а не на исполняемый файл, в котором работает интерпретатор Python. Если запускаемый сценарий отсутствует, первый элемент в *argv* может быть пустой строкой. Если этой функции не удаётся инициализировать [`sys.argv`](https://python-all.ru/3.10/library/sys.html#sys.argv), фатальная ситуация сигнализируется с помощью [`Py_FatalError()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_FatalError).371372Если *updatepath* равен нулю, на этом работа функции заканчивается. Если *updatepath* не равен нулю, функция также изменяет [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) по следующему алгоритму:373374- Если в `argv[0]` передано имя существующего сценария, то абсолютный путь к каталогу, в котором находится сценарий, добавляется в начало [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path).375- В противном случае (то есть если *argc* равен `0` или `argv[0]` не указывает на существующее имя файла), пустая строка добавляется в начало [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path), что эквивалентно добавлению текущего рабочего каталога (`"."`).376377Используйте [`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale) для декодирования строки байтов, чтобы получить строку `wchar_*`.378379> **Примечание**380>381> Рекомендуется, чтобы приложения, встраивающие интерпретатор Python для целей, отличных от выполнения одного скрипта, передавали `0` в качестве *updatepath*, и обновляли [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) самостоятельно, если это необходимо. См. [CVE-2008-5983](https://python-all.ru/3.10/c-api/init.html).382>383> В версиях до 3.1.3 того же эффекта можно достичь, вручную удалив первый элемент [`sys.path`](https://python-all.ru/3.10/library/sys.html#sys.path) после вызова [`PySys_SetArgv()`](https://python-all.ru/3.10/c-api/init.html#c.PySys_SetArgv), например используя:384>385> ```c386> PyRun_SimpleString("import sys; sys.path.pop(0)\n");387> ```388389Новое в версии 3.1.3.390391#### `void PySys_SetArgv(int argc, wchar_t **argv)`392393*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*394395Эта функция работает как [`PySys_SetArgvEx()`](https://python-all.ru/3.10/c-api/init.html#c.PySys_SetArgvEx) с *updatepath*, установленным в `1`, если только интерпретатор **python** не был запущен с [`-I`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-I).396397Используйте [`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale) для декодирования строки байтов, чтобы получить строку `wchar_*`.398399Изменено в версии 3.4: Значение *updatepath* зависит от [`-I`](https://python-all.ru/3.10/using/cmdline.html#cmdoption-I).400401#### `void Py_SetPythonHome(const wchar_t *home)`402403*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*404405Устанавливает домашний каталог по умолчанию, то есть расположение стандартных библиотек Python. См. [`PYTHONHOME`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONHOME) для пояснения значения строки аргумента.406407Аргумент должен указывать на строку символов, завершающуюся нулём, в статической памяти, содержимое которой не будет изменяться в течение всего времени выполнения программы. Никакой код в интерпретаторе Python не будет менять содержимое этой памяти.408409Используйте [`Py_DecodeLocale()`](https://python-all.ru/3.10/c-api/sys.html#c.Py_DecodeLocale) для декодирования строки байтов, чтобы получить строку `wchar_*`.410411#### `wchar_t *Py_GetPythonHome()`412413*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*414415Возвращает «домашний» каталог по умолчанию, то есть значение, установленное предыдущим вызовом [`Py_SetPythonHome()`](https://python-all.ru/3.10/c-api/init.html#c.Py_SetPythonHome), или значение переменной окружения [`PYTHONHOME`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONHOME), если она задана.416417Эту функцию не следует вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), иначе она возвращает `NULL`.418419Изменено в версии 3.10: Теперь возвращает `NULL`, если вызвано до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).420421## Состояние потока и глобальная блокировка интерпретатора422423Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python существует глобальная блокировка, называемая [глобальной блокировкой интерпретатора](https://python-all.ru/3.10/glossary.html#term-global-interpreter-lock) или [GIL](https://python-all.ru/3.10/glossary.html#term-GIL), которую текущий поток должен удерживать перед тем, как безопасно обращаться к объектам Python. Без этой блокировки даже простейшие операции могут вызывать проблемы в многопоточной программе: например, когда два потока одновременно увеличивают счётчик ссылок одного и того же объекта, счётчик может в итоге увеличиться только один раз вместо двух.424425Поэтому существует правило: только поток, захвативший [GIL](https://python-all.ru/3.10/glossary.html#term-GIL), может работать с объектами Python или вызывать функции Python/C API. Для эмуляции параллелизма выполнения интерпретатор регулярно пытается переключать потоки (см. [`sys.setswitchinterval()`](https://python-all.ru/3.10/library/sys.html#sys.setswitchinterval)). Блокировка также освобождается вокруг потенциально блокирующих операций ввода-вывода, таких как чтение или запись файла, чтобы тем временем могли работать другие потоки Python.426427Интерпретатор Python хранит некоторую служебную информацию, специфичную для потока, в структуре данных, называемой [`PyThreadState`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState). Существует также одна глобальная переменная, указывающая на текущий [`PyThreadState`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState): её можно получить с помощью [`PyThreadState_Get()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Get).428429### Освобождение GIL из кода расширения430431Большая часть кода расширения, работающего с [GIL](https://python-all.ru/3.10/glossary.html#term-GIL), имеет следующую простую структуру:432433```c434Save the thread state in a local variable.435Release the global interpreter lock.436... Do some blocking I/O operation ...437Reacquire the global interpreter lock.438Restore the thread state from the local variable.439```440441Это настолько распространено, что существует пара макросов для упрощения:442443```c444Py_BEGIN_ALLOW_THREADS445... Do some blocking I/O operation ...446Py_END_ALLOW_THREADS447```448449Макрос [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_BEGIN_ALLOW_THREADS) открывает новый блок и объявляет скрытую локальную переменную; макрос [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS) закрывает блок.450451Приведённый выше блок раскрывается в следующий код:452453```c454PyThreadState *_save;455456_save = PyEval_SaveThread();457... Do some blocking I/O operation ...458PyEval_RestoreThread(_save);459```460461Вот как работают эти функции: глобальная блокировка интерпретатора используется для защиты указателя на текущее состояние потока. При освобождении блокировки и сохранении состояния потока указатель на текущее состояние потока должен быть получен до освобождения блокировки (поскольку другой поток может немедленно захватить блокировку и сохранить своё состояние потока в глобальной переменной). И наоборот, при захвате блокировки и восстановлении состояния потока блокировка должна быть захвачена до сохранения указателя на состояние потока.462463> **Примечание**464>465> Вызов системных функций ввода-вывода – это наиболее распространённый случай освобождения GIL, но он также может быть полезен перед вызовом длительных вычислений, не требующих доступа к объектам Python, таких как функции сжатия или шифрования, работающие с буферами памяти. Например, стандартные модули [`zlib`](https://python-all.ru/3.10/library/zlib.html#module-zlib) и [`hashlib`](https://python-all.ru/3.10/library/hashlib.html#module-hashlib) освобождают GIL при сжатии или хешировании данных.466467### Потоки, созданные не из Python468469Когда потоки создаются с помощью специализированных Python API (например, модуля [`threading`](https://python-all.ru/3.10/library/threading.html#module-threading)), с ними автоматически связывается состояние потока, и приведённый выше код корректен. Однако, когда потоки создаются из C (например, сторонней библиотекой с собственным управлением потоками), они не удерживают GIL и для них не существует структуры состояния потока.470471Если необходимо вызвать код Python из этих потоков (часто это будет частью API колбэков, предоставляемого упомянутой сторонней библиотекой), сначала нужно зарегистрировать эти потоки в интерпретаторе, создав структуру данных состояния потока, затем захватить GIL и, наконец, сохранить указатель на их состояние потока, прежде чем можно будет начать использовать Python/C API. После завершения следует сбросить указатель состояния потока, освободить GIL и освободить структуру данных состояния потока.472473Функции [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release) делают всё вышеописанное автоматически. Типичный способ вызова Python из потока C:474475```c476PyGILState_STATE gstate;477gstate = PyGILState_Ensure();478479/* Выполнить действия Python здесь. */480result = CallSomeFunction();481/* вычислить результат или обработать исключение */482483/* Освободить поток. После этой точки API Python не допускается. */484PyGILState_Release(gstate);485```486487Обратите внимание, что функции `PyGILState_*` предполагают наличие только одного глобального интерпретатора (создаваемого автоматически с помощью [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize)). Python поддерживает создание дополнительных интерпретаторов (с помощью [`Py_NewInterpreter()`](https://python-all.ru/3.10/c-api/init.html#c.Py_NewInterpreter)), но смешивание нескольких интерпретаторов и API `PyGILState_*` не поддерживается.488489### Предостережения относительно fork()490491Ещё одна важная особенность потоков – их поведение при вызове C `fork()`. На большинстве систем с `fork()` после fork процесса остаётся только тот поток, который вызвал fork. Это оказывает конкретное влияние как на обработку блокировок, так и на всё сохранённое состояние в среде выполнения CPython.492493То, что остаётся только «текущий» поток, означает, что любые блокировки, удерживаемые другими потоками, никогда не будут освобождены. Python решает эту проблему для [`os.fork()`](https://python-all.ru/3.10/library/os.html#os.fork), захватывая блокировки, которые использует внутри, до вызова fork и освобождая их после. Кроме того, он сбрасывает любые [объекты блокировок](https://python-all.ru/3.10/library/threading.html#lock-objects) в дочернем процессе. При расширении или встраивании Python невозможно сообщить Python о дополнительных (не-Python) блокировках, которые необходимо захватить до fork или сбросить после. Для достижения того же эффекта потребуется использовать средства ОС, такие как `pthread_atfork()`. Кроме того, при расширении или встраивании Python вызов `fork()` напрямую, а не через [`os.fork()`](https://python-all.ru/3.10/library/os.html#os.fork) (и возврат в Python или вызов Python) может привести к взаимоблокировке из-за того, что одна из внутренних блокировок Python удерживается потоком, который перестаёт существовать после fork. [`PyOS_AfterFork_Child()`](https://python-all.ru/3.10/c-api/sys.html#c.PyOS_AfterFork_Child) пытается сбросить необходимые блокировки, но не всегда может это сделать.494495Тот факт, что все остальные потоки исчезают, также означает, что состояние среды выполнения CPython должно быть правильно очищено, что и делает [`os.fork()`](https://python-all.ru/3.10/library/os.html#os.fork). Это означает завершение всех остальных объектов [`PyThreadState`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState), принадлежащих текущему интерпретатору, и всех остальных объектов [`PyInterpreterState`](https://python-all.ru/3.10/c-api/init.html#c.PyInterpreterState). Из-за этого и особой природы [«главного» интерпретатора](https://python-all.ru/3.10/c-api/init.html#sub-interpreter-support), `fork()` следует вызывать только в «главном» потоке этого интерпретатора, где изначально была инициализирована глобальная среда выполнения CPython. Единственное исключение – если `exec()` будет вызван сразу после.496497### API высокого уровня498499Это наиболее часто используемые типы и функции при написании кода C-расширения или при встраивании интерпретатора Python:500501#### `type PyInterpreterState`502503*Часть [Limited API](https://python-all.ru/3.10/c-api/stable.html#stable) (как непрозрачная структура).*504505Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, разделяют администрирование модулей и несколько других внутренних элементов. В этой структуре нет открытых членов.506507Потоки, принадлежащие разным интерпретаторам, изначально не разделяют ничего, кроме состояния процесса, такого как доступная память, открытые файловые дескрипторы и т.п. Глобальная блокировка интерпретатора также разделяется всеми потоками, независимо от того, какому интерпретатору они принадлежат.508509#### `type PyThreadState`510511*Часть [Limited API](https://python-all.ru/3.10/c-api/stable.html#stable) (как непрозрачная структура).*512513Эта структура данных представляет состояние одного потока. Единственным открытым членом данных является `interp` (`PyInterpreterState*`), который указывает на состояние интерпретатора этого потока.514515#### `void PyEval_InitThreads()`516517*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*518519Устаревшая функция, которая ничего не делает.520521В Python 3.6 и старше эта функция создавала GIL, если его не существовало.522523Изменено в версии 3.9: Теперь функция ничего не делает.524525Изменено в версии 3.7: Теперь эта функция вызывается [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize), так что вам больше не нужно вызывать её самостоятельно.526527Изменено в версии 3.2: Эту функцию больше нельзя вызывать до [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).528529Устарело с версии 3.9, будет удалено в версии 3.11.530531#### `int PyEval_ThreadsInitialized()`532533*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*534535Возвращает ненулевое значение, если [`PyEval_InitThreads()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_InitThreads) был вызван. Эту функцию можно вызывать без удержания GIL, поэтому её можно использовать для избежания вызовов API блокировок при однопоточном выполнении.536537Изменено в версии 3.7: теперь [GIL](https://python-all.ru/3.10/glossary.html#term-GIL) инициализируется с помощью [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).538539Устарело с версии 3.9, будет удалено в версии 3.11.540541#### `PyThreadState *PyEval_SaveThread()`542543*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*544545Освобождает глобальную блокировку интерпретатора (если она была создана) и сбрасывает состояние потока на `NULL`, возвращая предыдущее состояние потока (которое не равно `NULL`). Если блокировка была создана, текущий поток должен был её захватить.546547#### `void PyEval_RestoreThread(PyThreadState *tstate)`548549*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*550551Захватывает глобальную блокировку интерпретатора (если она была создана) и устанавливает состояние потока в *tstate*, которое не должно быть `NULL`. Если блокировка была создана, текущий поток не должен был её захватить, иначе возникает взаимоблокировка.552553> **Примечание**554>555> Вызов этой функции из потока в момент завершения работы среды выполнения приведёт к завершению потока, даже если поток не был создан Python. Для проверки того, завершается ли интерпретатор, перед вызовом этой функции можно использовать `_Py_IsFinalizing()` или [`sys.is_finalizing()`](https://python-all.ru/3.10/library/sys.html#sys.is_finalizing), чтобы избежать нежелательного завершения.556557#### `PyThreadState *PyThreadState_Get()`558559*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*560561Возвращает текущее состояние потока. Глобальная блокировка интерпретатора должна быть захвачена. Если текущее состояние потока равно `NULL`, вызывается фатальная ошибка (так что вызывающему коду не нужно проверять на `NULL`).562563#### `PyThreadState *PyThreadState_Swap(PyThreadState *tstate)`564565*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*566567Заменяет текущее состояние потока на состояние потока, заданное аргументом *tstate*, который может быть `NULL`. Глобальная блокировка интерпретатора должна быть удержана и не освобождается.568569Следующие функции используют локальное хранилище потока и несовместимы с подынтерпретаторами:570571#### `PyGILState_STATE PyGILState_Ensure()`572573*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*574575Обеспечивает, что текущий поток готов к вызову Python C API независимо от текущего состояния Python или глобальной блокировки интерпретатора. Этот вызов может вызываться потоком сколько угодно раз, при условии, что каждый вызов завершается вызовом [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release). В общем случае другие API, связанные с потоками, могут использоваться между вызовами [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release), если состояние потока будет восстановлено в предыдущее состояние перед Release(). Например, обычное использование макросов [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_BEGIN_ALLOW_THREADS) и [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS) допустимо.576577Возвращаемое значение – это непрозрачный «дескриптор» состояния потока на момент вызова [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure), и его необходимо передать в [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release), чтобы гарантировать, что Python останется в том же состоянии. Хотя рекурсивные вызовы разрешены, эти дескрипторы *нельзя* совместно использовать – каждый уникальный вызов [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) должен сохранить свой дескриптор для вызова [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release).578579Когда функция возвращает управление, текущий поток будет удерживать GIL и сможет вызывать произвольный код Python. Сбой является фатальной ошибкой.580581> **Примечание**582>583> Вызов этой функции из потока в момент завершения работы среды выполнения приведёт к завершению потока, даже если поток не был создан Python. Для проверки того, завершается ли интерпретатор, перед вызовом этой функции можно использовать `_Py_IsFinalizing()` или [`sys.is_finalizing()`](https://python-all.ru/3.10/library/sys.html#sys.is_finalizing), чтобы избежать нежелательного завершения.584585#### `void PyGILState_Release(PyGILState_STATE)`586587*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*588589Освобождает любые ресурсы, полученные ранее. После этого вызова состояние Python будет таким же, как до соответствующего вызова [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) (но обычно это состояние неизвестно вызывающему, поэтому используется GILState API).590591Каждый вызов [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) должен сопровождаться вызовом [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release) в том же потоке.592593#### `PyThreadState *PyGILState_GetThisThreadState()`594595*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*596597Возвращает состояние текущего потока. Может вернуть `NULL`, если на текущем потоке не использовался GILState API. Обратите внимание, что главный поток всегда имеет такое состояние, даже если для него не вызывался auto-thread-state. Это вспомогательная/диагностическая функция.598599#### `int PyGILState_Check()`600601Возвращает `1`, если текущий поток удерживает GIL, и `0` в противном случае. Эту функцию можно вызывать из любого потока в любое время. Только если состояние потока Python инициализировано и он в данный момент удерживает GIL, она вернёт `1`. Это в основном вспомогательная/диагностическая функция. Она может быть полезна, например, в контекстах колбэков или функциях выделения памяти, когда знание того, что GIL заблокирован, позволяет вызывающей стороне выполнять чувствительные действия или вести себя иначе.602603Новое в версии 3.4.604605Следующие макросы обычно используются без точки с запятой в конце; примеры использования можно найти в дистрибутиве исходного кода Python.606607#### `Py_BEGIN_ALLOW_THREADS`608609*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*610611Этот макрос раскрывается в `{ PyThreadState *_save; _save = PyEval_SaveThread();`. Обратите внимание, что он содержит открывающую фигурную скобку; она должна быть сопоставлена с последующим макросом [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS). См. выше дополнительное обсуждение этого макроса.612613#### `Py_END_ALLOW_THREADS`614615*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*616617Этот макрос раскрывается в `PyEval_RestoreThread(_save); }`. Обратите внимание, что он содержит закрывающую фигурную скобку; она должна быть сопоставлена с предыдущим макросом [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_BEGIN_ALLOW_THREADS). См. выше дополнительное обсуждение этого макроса.618619#### `Py_BLOCK_THREADS`620621*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*622623Этот макрос разворачивается в `PyEval_RestoreThread(_save);`: он эквивалентен [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS) без закрывающей фигурной скобки.624625#### `Py_UNBLOCK_THREADS`626627*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*628629Этот макрос разворачивается в `_save = PyEval_SaveThread();`: он эквивалентен [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.10/c-api/init.html#c.Py_BEGIN_ALLOW_THREADS) без открывающей фигурной скобки и объявления переменной.630631### Низкоуровневый API632633Все следующие функции должны вызываться после [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize).634635Изменено в версии 3.7: [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize) теперь инициализирует [GIL](https://python-all.ru/3.10/glossary.html#term-GIL).636637#### `PyInterpreterState *PyInterpreterState_New()`638639*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*640641Создаёт новый объект состояния интерпретатора. Глобальная блокировка интерпретатора может не удерживаться, но может удерживаться, если необходимо сериализовать вызовы этой функции.642643Возбуждает [событие аудита](https://python-all.ru/3.10/library/sys.html#auditing) `cpython.PyInterpreterState_New` без аргументов.644645#### `void PyInterpreterState_Clear(PyInterpreterState *interp)`646647*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*648649Сбрасывает всю информацию в объекте состояния интерпретатора. Глобальная блокировка интерпретатора должна удерживаться.650651Возбуждает [событие аудита](https://python-all.ru/3.10/library/sys.html#auditing) `cpython.PyInterpreterState_Clear` без аргументов.652653#### `void PyInterpreterState_Delete(PyInterpreterState *interp)`654655*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*656657Уничтожает объект состояния интерпретатора. Глобальная блокировка интерпретатора может не удерживаться. Состояние интерпретатора должно быть предварительно сброшено вызовом [`PyInterpreterState_Clear()`](https://python-all.ru/3.10/c-api/init.html#c.PyInterpreterState_Clear).658659#### `PyThreadState *PyThreadState_New(PyInterpreterState *interp)`660661*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*662663Создаёт новый объект состояния потока, принадлежащий данному объекту интерпретатора. Глобальная блокировка интерпретатора может не удерживаться, но может удерживаться, если необходимо сериализовать вызовы этой функции.664665#### `void PyThreadState_Clear(PyThreadState *tstate)`666667*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*668669Сбрасывает всю информацию в объекте состояния потока. Глобальная блокировка интерпретатора должна удерживаться.670671Изменено в версии 3.9: Теперь эта функция вызывает колбэк `PyThreadState.on_delete`. Ранее это происходило в [`PyThreadState_Delete()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Delete).672673#### `void PyThreadState_Delete(PyThreadState *tstate)`674675*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*676677Уничтожает объект состояния потока. Глобальная блокировка интерпретатора может не удерживаться. Состояние потока должно быть предварительно сброшено вызовом [`PyThreadState_Clear()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Clear).678679#### `void PyThreadState_DeleteCurrent(void)`680681Уничтожает текущее состояние потока и освобождает глобальную блокировку интерпретатора. Как и [`PyThreadState_Delete()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Delete), глобальную блокировку интерпретатора не требуется удерживать. Состояние потока должно быть сброшено предыдущим вызовом [`PyThreadState_Clear()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Clear).682683#### `PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate)`684685*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.10.*686687Возвращает текущий кадр состояния потока Python *tstate*.688689Возвращает [сильную ссылку](https://python-all.ru/3.10/glossary.html#term-strong-reference). Возвращает `NULL`, если в данный момент кадр не выполняется.690691См. также [`PyEval_GetFrame()`](https://python-all.ru/3.10/c-api/reflection.html#c.PyEval_GetFrame).692693*tstate* не должно быть `NULL`.694695Новое в версии 3.9.696697#### `uint64_t PyThreadState_GetID(PyThreadState *tstate)`698699*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.10.*700701Возвращает уникальный идентификатор состояния потока Python для *tstate*.702703*tstate* не должно быть `NULL`.704705Новое в версии 3.9.706707#### `PyInterpreterState *PyThreadState_GetInterpreter(PyThreadState *tstate)`708709*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.10.*710711Возвращает интерпретатор состояния потока Python *tstate*.712713*tstate* не должно быть `NULL`.714715Новое в версии 3.9.716717#### `PyInterpreterState *PyInterpreterState_Get(void)`718719*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.9.*720721Получает текущий интерпретатор.722723Вызывает фатальную ошибку, если отсутствует текущее состояние потока Python или текущий интерпретатор. Функция не может вернуть NULL.724725Вызывающий должен удерживать GIL.726727Новое в версии 3.9.728729#### `int64_t PyInterpreterState_GetID(PyInterpreterState *interp)`730731*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*732733Возвращает уникальный идентификатор интерпретатора. Если при этом произошла ошибка, возвращается `-1` и устанавливается исключение.734735Вызывающий должен удерживать GIL.736737Добавлено в версии 3.7.738739#### `PyObject *PyInterpreterState_GetDict(PyInterpreterState *interp)`740741*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) с версии 3.8.*742743Возвращает словарь, в котором могут храниться данные, специфичные для интерпретатора. Если эта функция возвращает `NULL`, исключение не было возбуждено, и вызывающий код должен считать, что словарь данных интерпретатора недоступен.744745Это не замена [`PyModule_GetState()`](https://python-all.ru/3.10/c-api/module.html#c.PyModule_GetState), который расширения должны использовать для хранения информации о состоянии интерпретатора.746747Новое в версии 3.8.748749#### `typedef PyObject *(*_PyFrameEvalFunction)(PyThreadState *tstate, PyFrameObject *frame, int throwflag)`750751Тип функции вычисления фрейма.752753Параметр *throwflag* используется методом `throw()` генераторов: если он не равен нулю, обрабатывается текущее исключение.754755Изменено в версии 3.9: Теперь функция принимает параметр *tstate*.756757#### `_PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)`758759Возвращает функцию вычисления фрейма.760761См. [**PEP 523**](https://python-all.ru/3.10/c-api/init.html) «Добавление API вычисления фрейма в CPython».762763Новое в версии 3.9.764765#### `void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame)`766767Устанавливает функцию вычисления фрейма.768769См. [**PEP 523**](https://python-all.ru/3.10/c-api/init.html) «Добавление API вычисления фрейма в CPython».770771Новое в версии 3.9.772773#### `PyObject *PyThreadState_GetDict()`774775*Возвращаемое значение: заимствованная ссылка.*776777*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*778779Возвращает словарь, в котором расширения могут хранить информацию о состоянии, специфичном для потока. Каждое расширение должно использовать уникальный ключ для хранения состояния в словаре. Допускается вызывать эту функцию, когда нет текущего состояния потока. Если эта функция возвращает `NULL`, исключение не было возбуждено, и вызывающий должен предполагать, что текущее состояние потока недоступно.780781#### `int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)`782783*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*784785Асинхронно возбуждает исключение в потоке. Аргумент *id* – это идентификатор потока целевого потока; *exc* – это объект исключения, которое нужно возбудить. Эта функция не крадёт ссылки на *exc*. Для предотвращения наивного misuse требуется написать собственное C-расширение для её вызова. Должна вызываться с удержанием GIL. Возвращает количество изменённых состояний потока; обычно это единица, но будет нулём, если идентификатор потока не найден. Если *exc* равно `NULL`, отложенное исключение (если есть) для потока очищается. Эта функция не возбуждает исключений.786787Изменено в версии 3.7: тип параметра *id* изменён с `long` на `unsigned long`.788789#### `void PyEval_AcquireThread(PyThreadState *tstate)`790791*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*792793Захватывает глобальную блокировку интерпретатора и устанавливает текущее состояние потока в *tstate*, которое не должно быть `NULL`. Блокировка должна быть создана ранее. Если этот поток уже удерживает блокировку, возникает взаимоблокировка.794795> **Примечание**796>797> Вызов этой функции из потока в момент завершения работы среды выполнения приведёт к завершению потока, даже если поток не был создан Python. Для проверки того, завершается ли интерпретатор, перед вызовом этой функции можно использовать `_Py_IsFinalizing()` или [`sys.is_finalizing()`](https://python-all.ru/3.10/library/sys.html#sys.is_finalizing), чтобы избежать нежелательного завершения.798799Изменено в версии 3.8: Функция обновлена для согласованности с [`PyEval_RestoreThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_RestoreThread), [`Py_END_ALLOW_THREADS()`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS) и [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure), и теперь завершает текущий поток, если вызвана во время завершения работы интерпретатора.800801[`PyEval_RestoreThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_RestoreThread) – функция более высокого уровня, которая всегда доступна (даже если потоки не были инициализированы).802803#### `void PyEval_ReleaseThread(PyThreadState *tstate)`804805*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*806807Сбрасывает текущее состояние потока в `NULL` и освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и должна удерживаться текущим потоком. Аргумент *tstate*, который не должен быть `NULL`, используется только для проверки, что он представляет текущее состояние потока – если это не так, выводится фатальная ошибка.808809[`PyEval_SaveThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SaveThread) – функция более высокого уровня, которая всегда доступна (даже если потоки не были инициализированы).810811#### `void PyEval_AcquireLock()`812813*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*814815Захватывает глобальную блокировку интерпретатора. Блокировка должна быть создана заранее. Если этот поток уже удерживает блокировку, возникает взаимоблокировка.816817Устарело с версии 3.2: Эта функция не обновляет текущее состояние потока. Вместо неё используйте [`PyEval_RestoreThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_RestoreThread) или [`PyEval_AcquireThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_AcquireThread).818819> **Примечание**820>821> Вызов этой функции из потока в момент завершения работы среды выполнения приведёт к завершению потока, даже если поток не был создан Python. Для проверки того, завершается ли интерпретатор, перед вызовом этой функции можно использовать `_Py_IsFinalizing()` или [`sys.is_finalizing()`](https://python-all.ru/3.10/library/sys.html#sys.is_finalizing), чтобы избежать нежелательного завершения.822823Изменено в версии 3.8: Функция обновлена для согласованности с [`PyEval_RestoreThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_RestoreThread), [`Py_END_ALLOW_THREADS()`](https://python-all.ru/3.10/c-api/init.html#c.Py_END_ALLOW_THREADS) и [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure), и теперь завершает текущий поток, если вызвана во время завершения работы интерпретатора.824825#### `void PyEval_ReleaseLock()`826827*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*828829Освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана заранее.830831Устарело с версии 3.2: Эта функция не обновляет текущее состояние потока. Вместо неё используйте [`PyEval_SaveThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SaveThread) или [`PyEval_ReleaseThread()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_ReleaseThread).832833## Поддержка под-интерпретаторов834835Хотя в большинстве случаев достаточно встроить один интерпретатор Python, бывают ситуации, когда требуется создать несколько независимых интерпретаторов в одном процессе и даже в одном потоке. Под-интерпретаторы позволяют это сделать.836837«Главный» интерпретатор – это первый интерпретатор, создаваемый при инициализации среды выполнения. Обычно он является единственным интерпретатором Python в процессе. В отличие от под-интерпретаторов, главный интерпретатор обладает уникальными общепроцессными обязанностями, такими как обработка сигналов. Он также отвечает за выполнение при инициализации среды выполнения и обычно является активным интерпретатором при завершении работы среды выполнения. Функция [`PyInterpreterState_Main()`](https://python-all.ru/3.10/c-api/init.html#c.PyInterpreterState_Main) возвращает указатель на его состояние.838839Переключаться между под-интерпретаторами можно с помощью функции [`PyThreadState_Swap()`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState_Swap). Создавать и удалять их можно с помощью следующих функций:840841#### `PyThreadState *Py_NewInterpreter()`842843*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*844845Создаёт новый под-интерпретатор. Это (почти) полностью независимое окружение для выполнения кода Python. В частности, новый интерпретатор имеет отдельные, независимые версии всех импортированных модулей, включая фундаментальные модули [`builtins`](https://python-all.ru/3.10/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.10/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.10/library/sys.html#module-sys). Таблица загруженных модулей (`sys.modules`) и путь поиска модулей (`sys.path`) также отдельные. В новом окружении нет переменной `sys.argv` . У него есть новые файловые объекты стандартных потоков ввода-вывода `sys.stdin`, `sys.stdout` и `sys.stderr` (однако они ссылаются на те же нижележащие файловые дескрипторы).846847Возвращаемое значение указывает на первое состояние потока, созданное в новом под-интерпретаторе. Это состояние потока устанавливается в текущем состоянии потока. Обратите внимание, что никакой реальный поток не создаётся; см. обсуждение состояний потока ниже. Если создание нового интерпретатора оказалось неудачным, возвращается `NULL`; никакое исключение не устанавливается, поскольку состояние исключения хранится в текущем состоянии потока, и текущее состояние потока может отсутствовать. (Как и во всех остальных функциях Python/C API, глобальная блокировка интерпретатора должна удерживаться перед вызовом этой функции и остаётся удерживаться при возврате; однако, в отличие от большинства других функций Python/C API, при входе не обязательно должно быть текущее состояние потока.)848849Модули расширения совместно используются (под-)интерпретаторами следующим образом:850851- Для модулей, использующих многофазную инициализацию, например [`PyModule_FromDefAndSpec()`](https://python-all.ru/3.10/c-api/module.html#c.PyModule_FromDefAndSpec), для каждого интерпретатора создаётся и инициализируется отдельный объект модуля. Между этими объектами модулей совместно используются только статические и глобальные переменные на уровне C.852- Для модулей, использующих однофазную инициализацию, например [`PyModule_Create()`](https://python-all.ru/3.10/c-api/module.html#c.PyModule_Create), при первом импорте определённого расширения оно инициализируется обычным образом, и (поверхностная) копия его словаря модуля сохраняется. Когда то же расширение импортируется другим (под-)интерпретатором, новый модуль инициализируется и заполняется содержимым этой копии; функция `init` расширения не вызывается. Таким образом, объекты в словаре модуля оказываются общими для (под-)интерпретаторов, что может вызывать нежелательное поведение (см. [Ошибки и предостережения](https://python-all.ru/3.10/c-api/init.html#bugs-and-caveats) ниже).853854 Обратите внимание, что это отличается от ситуации, когда расширение импортируется после полной повторной инициализации интерпретатора вызовом [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx) и [`Py_Initialize()`](https://python-all.ru/3.10/c-api/init.html#c.Py_Initialize); в этом случае функция `initmodule` расширения *вызывается* снова. Как и при многофазной инициализации, это означает, что между этими модулями совместно используются только статические и глобальные переменные на уровне C.855856#### `void Py_EndInterpreter(PyThreadState *tstate)`857858*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*859860Уничтожает (под-)интерпретатор, представленный данным состоянием потока. Данное состояние потока должно быть текущим состоянием потока. См. обсуждение состояний потока ниже. Когда вызов возвращается, текущее состояние потока равно `NULL`. Все состояния потока, связанные с этим интерпретатором, уничтожаются. (Глобальная блокировка интерпретатора должна удерживаться перед вызовом этой функции и всё ещё удерживается при возврате.) [`Py_FinalizeEx()`](https://python-all.ru/3.10/c-api/init.html#c.Py_FinalizeEx) уничтожит все под-интерпретаторы, которые не были явно уничтожены к этому моменту.861862### Ошибки и предостережения863864Поскольку под-интерпретаторы (и главный интерпретатор) являются частью одного процесса, изоляция между ними не идеальна – например, с помощью низкоуровневых файловых операций, таких как [`os.close()`](https://python-all.ru/3.10/library/os.html#os.close), они могут (случайно или намеренно) влиять на открытые файлы друг друга. Из-за того, как расширения совместно используются (под-)интерпретаторами, некоторые расширения могут работать некорректно; это особенно вероятно при использовании однофазной инициализации или (статических) глобальных переменных. Можно вставлять объекты, созданные в одном под-интерпретаторе, в пространство имён другого (под-)интерпретатора; этого следует избегать, если возможно.865866Следует проявлять особую осторожность, чтобы избежать совместного использования пользовательских функций, методов, экземпляров или классов между под-интерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут повлиять на словарь загруженных модулей не того (под-)интерпретатора. Не менее важно избегать совместного использования объектов, из которых доступны вышеперечисленные.867868Также обратите внимание, что комбинирование этой функциональности с API `PyGILState_*` является деликатным, поскольку эти API предполагают взаимно однозначное соответствие между состояниями потоков Python и потоками уровня ОС, а это предположение нарушается наличием под-интерпретаторов. Настоятельно рекомендуется не переключать под-интерпретаторы между парой соответствующих вызовов [`PyGILState_Ensure()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.10/c-api/init.html#c.PyGILState_Release). Более того, расширения (такие как [`ctypes`](https://python-all.ru/3.10/library/ctypes.html#module-ctypes)), использующие эти API для вызова кода Python из потоков, созданных не в Python, вероятно, будут работать неправильно при использовании под-интерпретаторов.869870## Асинхронные уведомления871872Предоставляется механизм для асинхронных уведомлений основному потоку интерпретатора. Эти уведомления имеют форму указателя на функцию и аргумента в виде указателя void.873874#### `int Py_AddPendingCall(int (*func)(void*), void *arg, )`875876*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*877878Планирует вызов функции из основного потока интерпретатора. В случае успеха возвращается `0`, и *func* помещается в очередь для вызова в основном потоке. В случае неудачи возвращается `-1` без установки какого-либо исключения.879880При успешной постановке в очередь *func* будет *в конечном итоге* вызвана из основного потока интерпретатора с аргументом *arg*. Она будет вызвана асинхронно по отношению к нормально выполняющемуся коду Python, но при соблюдении обоих этих условий:881882- на границе [байткода](https://python-all.ru/3.10/glossary.html#term-bytecode);883- при этом главный поток удерживает [глобальную блокировку интерпретатора](https://python-all.ru/3.10/glossary.html#term-global-interpreter-lock) (поэтому *func* может использовать полный C API).884885*func* должна возвращать `0` при успехе или `-1` при неудаче с установленным исключением. *func* не будет прервана для рекурсивного выполнения другого асинхронного уведомления, но её всё ещё можно прервать для переключения потоков, если глобальная блокировка интерпретатора освобождена.886887Для выполнения этой функции не требуется текущее состояние потока, и ей не нужна глобальная блокировка интерпретатора.888889Для вызова этой функции в под-интерпретаторе вызывающий должен удерживать GIL. В противном случае функция *func* может быть запланирована к вызову из неправильного интерпретатора.890891> **Предупреждение**892>893> Это низкоуровневая функция, полезная только в особых случаях. Нет гарантии, что *func* будет вызвана максимально быстро. Если главный поток занят выполнением системного вызова, *func* не будет вызвана до возврата из системного вызова. Эта функция в целом **не** подходит для вызова кода Python из произвольных C-потоков. Вместо неё используйте [PyGILState API](https://python-all.ru/3.10/c-api/init.html#gilstate).894895Изменено в версии 3.9: Если эта функция вызывается в подынтерпретаторе, функция *func* теперь планируется для вызова из подынтерпретатора, а не из основного интерпретатора. Каждый подынтерпретатор теперь имеет свой собственный список запланированных вызовов.896897Новое в версии 3.1.898899## Профилирование и трассировка900901Интерпретатор Python предоставляет низкоуровневую поддержку для подключения средств профилирования и трассировки выполнения. Они используются в инструментах профилирования, отладки и анализа покрытия.902903Этот C-интерфейс позволяет коду профилирования или трассировки избежать накладных расходов на вызов через вызываемые объекты уровня Python, выполняя вместо этого прямой вызов C-функции. Основные характеристики механизма не изменились; интерфейс позволяет устанавливать функции трассировки для каждого потока, а базовые события, сообщаемые функции трассировки, такие же, как и в предыдущих версиях для функций трассировки уровня Python.904905#### `typedef int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)`906907Тип функции трассировки, регистрируемой с помощью [`PyEval_SetProfile()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SetProfile) и [`PyEval_SetTrace()`](https://python-all.ru/3.10/c-api/init.html#c.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*:908909| Значение *what* | Смысл *arg* |910| --- | --- |911| `PyTrace_CALL` | Всегда [`Py_None`](https://python-all.ru/3.10/c-api/none.html#c.Py_None). |912| `PyTrace_EXCEPTION` | Информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/3.10/library/sys.html#sys.exc_info). |913| `PyTrace_LINE` | Всегда [`Py_None`](https://python-all.ru/3.10/c-api/none.html#c.Py_None). |914| `PyTrace_RETURN` | Значение, возвращаемое вызывающему коду, или `NULL`, если вызвано исключением. |915| `PyTrace_C_CALL` | Вызываемый объект функции. |916| `PyTrace_C_EXCEPTION` | Вызываемый объект функции. |917| `PyTrace_C_RETURN` | Вызываемый объект функции. |918| `PyTrace_OPCODE` | Всегда [`Py_None`](https://python-all.ru/3.10/c-api/none.html#c.Py_None). |919920#### `int PyTrace_CALL`921922Значение параметра *what* для функции [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда сообщается о новом вызове функции или метода, или о новом входе в генератор. Обратите внимание, что создание итератора для функции-генератора не сообщается, поскольку в соответствующем фрейме не происходит передачи управления байт-коду Python.923924#### `int PyTrace_EXCEPTION`925926Значение параметра *what* в функции [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда возникло исключение. Функция колбэка вызывается с этим значением для *what* после обработки любого байт-кода, после которого исключение оказывается установленным в выполняемом фрейме. Эффект этого заключается в том, что по мере распространения исключения, вызывающего раскрутку стека Python, колбэк вызывается при возврате в каждый фрейм по мере распространения исключения. Только функции трассировки получают эти события; профилировщику они не нужны.927928#### `int PyTrace_LINE`929930Значение, передаваемое как параметр *what* в функцию [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc) (но не в функцию профилирования), когда сообщается о событии номера строки. Его можно отключить для фрейма, установив `f_trace_lines` в *0* на этом фрейме.931932#### `int PyTrace_RETURN`933934Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда вызов собирается вернуться.935936#### `int PyTrace_C_CALL`937938Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда собирается быть вызвана C-функция.939940#### `int PyTrace_C_EXCEPTION`941942Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда C-функция вызвала исключение.943944#### `int PyTrace_C_RETURN`945946Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc), когда C-функция вернулась.947948#### `int PyTrace_OPCODE`949950Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3.10/c-api/init.html#c.Py_tracefunc) (но не функций профилирования), когда собирается быть выполнен новый опкод. Это событие не генерируется по умолчанию: его нужно явно запросить, установив `f_trace_opcodes` в *1* во фрейме.951952#### `void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)`953954Устанавливает функцию профилирования в *func*. Параметр *obj* передаётся функции в качестве первого аргумента; это может быть любой объект Python или `NULL`. Если функции профилирования нужно поддерживать состояние, использование разных значений *obj* для каждого потока предоставляет удобное и потокобезопасное место для его хранения. Функция профилирования вызывается для всех отслеживаемых событий, кроме `PyTrace_LINE`, `PyTrace_OPCODE` и `PyTrace_EXCEPTION`.955956Вызывающий должен удерживать [GIL](https://python-all.ru/3.10/glossary.html#term-GIL).957958#### `void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)`959960Устанавливает функцию трассировки в *func*. Это похоже на [`PyEval_SetProfile()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SetProfile), за исключением того, что функция трассировки получает события номеров строк и события на каждую операцию, но не получает событий, связанных с вызовом объектов функций C. Любая функция трассировки, зарегистрированная через [`PyEval_SetTrace()`](https://python-all.ru/3.10/c-api/init.html#c.PyEval_SetTrace), не будет получать `PyTrace_C_CALL`, `PyTrace_C_EXCEPTION` или `PyTrace_C_RETURN` в качестве значения параметра *what*.961962Вызывающий должен удерживать [GIL](https://python-all.ru/3.10/glossary.html#term-GIL).963964## Поддержка расширенного отладчика965966Эти функции предназначены только для использования расширенными инструментами отладки.967968#### `PyInterpreterState *PyInterpreterState_Head()`969970Возвращает объект состояния интерпретатора, находящийся в начале списка всех таких объектов.971972#### `PyInterpreterState *PyInterpreterState_Main()`973974Возвращает объект состояния основного интерпретатора.975976#### `PyInterpreterState *PyInterpreterState_Next(PyInterpreterState *interp)`977978Возвращает следующий объект состояния интерпретатора после *interp* из списка всех таких объектов.979980#### `PyThreadState *PyInterpreterState_ThreadHead(PyInterpreterState *interp)`981982Возвращает указатель на первый объект [`PyThreadState`](https://python-all.ru/3.10/c-api/init.html#c.PyThreadState) в списке потоков, связанных с интерпретатором *interp*.983984#### `PyThreadState *PyThreadState_Next(PyThreadState *tstate)`985986Возвращает следующий объект состояния потока после *tstate* из списка всех таких объектов, принадлежащих тому же объекту [`PyInterpreterState`](https://python-all.ru/3.10/c-api/init.html#c.PyInterpreterState).987988## Поддержка локального хранилища потоков989990Интерпретатор Python предоставляет низкоуровневую поддержку для локального хранилища потока (TLS), которая оборачивает нижележащую нативную реализацию TLS для поддержки API потокового локального хранилища на уровне Python ([`threading.local`](https://python-all.ru/3.10/library/threading.html#threading.local)). API CPython на уровне C похожи на те, что предоставляются pthreads и Windows: используется ключ потока и функции для связывания значения `void*` с каждым потоком.991992GIL *не* нужно удерживать при вызове этих функций; они обеспечивают собственную блокировку.993994Обратите внимание, что `Python.h` не содержит объявления TLS-функций; для использования локальной памяти потока необходимо включить `pythread.h`.995996> **Примечание**997>998> Ни одна из этих функций API не занимается управлением памятью для значений `void*`. Их необходимо выделять и освобождать самостоятельно. Если значения `void*` оказываются `PyObject*`, эти функции также не выполняют над ними операции подсчёта ссылок.9991000### API потоково-специфичного хранилища (TSS)10011002API TSS введён для замены использования существующего TLS API в интерпретаторе CPython. Этот API использует новый тип [`Py_tss_t`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_t) вместо `int` для представления ключей потоков.10031004Добавлено в версии 3.7.10051006> **См. также**1007>1008> «Новый C-API для локальной памяти потока в CPython» ([**PEP 539**](https://python-all.ru/3.10/c-api/init.html))10091010#### `type Py_tss_t`10111012Эта структура данных представляет состояние ключа потока; её определение может зависеть от конкретной реализации TLS, и она содержит внутреннее поле, отражающее состояние инициализации ключа. Открытых членов этой структуры нет.10131014Если [Py\_LIMITED\_API](https://python-all.ru/3.10/c-api/stable.html#stable) не определён, допускается статическое размещение этого типа с помощью [`Py_tss_NEEDS_INIT`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_NEEDS_INIT).10151016#### `Py_tss_NEEDS_INIT`10171018Этот макрос раскрывается в инициализатор для переменных типа [`Py_tss_t`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_t). Обратите внимание, что этот макрос не будет определён вместе с [Py\_LIMITED\_API](https://python-all.ru/3.10/c-api/stable.html#stable).10191020#### Динамическое выделение10211022Динамическое выделение [`Py_tss_t`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_t) требуется в модулях расширения, собранных с [Py\_LIMITED\_API](https://python-all.ru/3.10/c-api/stable.html#stable), где статическое размещение этого типа невозможно из-за того, что его реализация скрыта во время сборки.10231024#### `Py_tss_t *PyThread_tss_alloc()`10251026*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10271028Возвращает значение, находящееся в том же состоянии, что и значение, инициализированное с помощью [`Py_tss_NEEDS_INIT`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_NEEDS_INIT), или `NULL` в случае ошибки динамического выделения.10291030#### `void PyThread_tss_free(Py_tss_t *key)`10311032*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10331034Освобождает заданный *key*, выделенный с помощью [`PyThread_tss_alloc()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_alloc), предварительно вызвав [`PyThread_tss_delete()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_delete), чтобы сбросить все привязанные к нему локальные данные потока. Эта операция ничего не делает, если аргумент *key* равен `NULL`.10351036> **Примечание**1037>1038> Освобождённый ключ становится висячим указателем. Следует сбросить ключ в *NULL*.10391040#### Методы10411042Параметр *key* этих функций не должен быть `NULL`. Кроме того, поведение [`PyThread_tss_set()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_set) и [`PyThread_tss_get()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_get) не определено, если заданный [`Py_tss_t`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_t) не был инициализирован с помощью [`PyThread_tss_create()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_create).10431044#### `int PyThread_tss_is_created(Py_tss_t *key)`10451046*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10471048Возвращает ненулевое значение, если заданный [`Py_tss_t`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_t) был инициализирован с помощью [`PyThread_tss_create()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_create).10491050#### `int PyThread_tss_create(Py_tss_t *key)`10511052*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10531054Возвращает нулевое значение при успешной инициализации TSS-ключа. Поведение не определено, если значение, на которое указывает аргумент *key*, не инициализировано с помощью [`Py_tss_NEEDS_INIT`](https://python-all.ru/3.10/c-api/init.html#c.Py_tss_NEEDS_INIT). Эту функцию можно вызывать для одного и того же ключа многократно – вызов для уже инициализированного ключа ничего не делает и сразу возвращает успех.10551056#### `void PyThread_tss_delete(Py_tss_t *key)`10571058*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10591060Уничтожает TSS-ключ, забывая связанные с ним значения во всех потоках, и переводит состояние инициализации ключа в «не инициализирован». Уничтоженный ключ можно повторно инициализировать с помощью [`PyThread_tss_create()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_tss_create). Эту функцию можно вызывать для одного и того же ключа многократно – вызов для уже уничтоженного ключа ничего не делает.10611062#### `int PyThread_tss_set(Py_tss_t *key, void *value)`10631064*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10651066Возвращает нулевое значение, указывающее на успешное связывание значения `void*` с ключом TSS в текущем потоке. Каждый поток имеет собственное отображение ключа на значение `void*`.10671068#### `void *PyThread_tss_get(Py_tss_t *key)`10691070*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable) начиная с версии 3.7.*10711072Возвращает значение `void*`, связанное с ключом TSS в текущем потоке. Возвращает `NULL`, если с ключом в текущем потоке не связано никакое значение.10731074### API локального хранилища потоков (TLS)10751076Устарело с версии 3.7: Этот API заменён [API поток-специфичного хранилища (TSS)](https://python-all.ru/3.10/c-api/init.html#thread-specific-storage-api).10771078> **Примечание**1079>1080> Эта версия API не поддерживает платформы, где нативный ключ TLS определён так, что его нельзя безопасно привести к `int`. На таких платформах [`PyThread_create_key()`](https://python-all.ru/3.10/c-api/init.html#c.PyThread_create_key) немедленно возвращает статус ошибки, а остальные функции TLS на таких платформах ничего не делают.10811082Из-за упомянутой выше проблемы совместимости эту версию API не следует использовать в новом коде.10831084#### `int PyThread_create_key()`10851086*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*10871088#### `void PyThread_delete_key(int key)`10891090*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*10911092#### `int PyThread_set_key_value(int key, void *value)`10931094*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*10951096#### `void *PyThread_get_key_value(int key)`10971098*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*10991100#### `void PyThread_delete_key_value(int key)`11011102*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*11031104#### `void PyThread_ReInitTLS()`11051106*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*1107