init.md
1> **Источник:** https://python-all.ru/3.0/c-api/init.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Инициализация, финализация и потоки89**\[Py\_Initialize\]void `Py_Initialize`()**1011Инициализирует интерпретатор Python. В приложении, встраивающем Python, её следует вызывать до использования любых других функций Python/C API; за исключением [`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName), [`PyEval_InitThreads`](https://python-all.ru/3.0/c-api/init.html#PyEval_InitThreads), [`PyEval_ReleaseLock`](https://python-all.ru/3.0/c-api/init.html#PyEval_ReleaseLock) и [`PyEval_AcquireLock`](https://python-all.ru/3.0/c-api/init.html#PyEval_AcquireLock). Эта функция инициализирует таблицу загруженных модулей (`sys.modules`) и создаёт фундаментальные модули [`builtins`](https://python-all.ru/3.0/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.0/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.0/library/sys.html#module-sys). Она также инициализирует путь поиска модулей (`sys.path`). Она не устанавливает `sys.argv`; для этого используйте [`PySys_SetArgv`](https://python-all.ru/3.0/c-api/init.html#PySys_SetArgv). Повторный вызов (без предшествующего вызова [`Py_Finalize`](https://python-all.ru/3.0/c-api/init.html#Py_Finalize)) ничего не делает. Возвращаемого значения нет; ошибка инициализации является фатальной.1213**\[Py\_InitializeEx\]void `Py_InitializeEx`(int *initsigs*)**1415Эта функция работает аналогично1617[`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize)1819, если2021*initsigs*2223равно 1. Если2425*initsigs*2627равно 0, она пропускает регистрацию обработчиков сигналов при инициализации, что может быть полезно при встраивании Python.2829**\[Py\_IsInitialized\]int `Py_IsInitialized`()**3031Возвращает true (ненулевое значение), если интерпретатор Python был инициализирован, и false (нуль) в противном случае. После вызова3233[`Py_Finalize`](https://python-all.ru/3.0/c-api/init.html#Py_Finalize)3435возвращает false до тех пор, пока не будет вызвана3637[`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize)3839снова.4041**\[Py\_Finalize\]void `Py_Finalize`()**4243Отменяет все инициализации, выполненные [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize) и последующим использованием функций Python/C API, и уничтожает все под-интерпретаторы (см. [`Py_NewInterpreter`](https://python-all.ru/3.0/c-api/init.html#Py_NewInterpreter) ниже), которые были созданы и ещё не уничтожены после последнего вызова [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize). В идеале, это освобождает всю память, выделенную интерпретатором Python. Повторный вызов (без предшествующего вызова [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize)) ничего не делает. Возвращаемого значения нет; ошибки во время завершения игнорируются.4445Эта функция предусмотрена по ряду причин. Встраивающее приложение может захотеть перезапустить Python без перезапуска самого приложения. Приложение, загрузившее интерпретатор Python из динамически загружаемой библиотеки (или DLL), может захотеть освободить всю память, выделенную Python, перед выгрузкой DLL. В процессе поиска утечек памяти в приложении разработчик может захотеть освободить всю память, выделенную Python, перед выходом из приложения.4647**Ошибки и предостережения:** Уничтожение модулей и объектов в модулях происходит в случайном порядке; это может приводить к сбоям деструкторов (методов [`__del__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__del__)) когда они зависят от других объектов (даже функций) или модулей. Динамически загруженные модули расширений, загруженные Python, не выгружаются. Небольшие объёмы памяти, выделенные интерпретатором Python, могут не освобождаться (если вы обнаружили утечку, пожалуйста, сообщите о ней). Память, занятая циклическими ссылками между объектами, не освобождается. Некоторое количество памяти, выделенное модулями расширений, может не освобождаться. Некоторые расширения могут работать некорректно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение вызывает [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize) и [`Py_Finalize`](https://python-all.ru/3.0/c-api/init.html#Py_Finalize) более одного раза.4849**\[Py\_NewInterpreter\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `Py_NewInterpreter`()**5051Создаёт новый под-интерпретатор. Это (почти) полностью изолированное окружение для выполнения кода Python. В частности, новый интерпретатор имеет отдельные, независимые версии всех импортированных модулей, включая фундаментальные модули [`builtins`](https://python-all.ru/3.0/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.0/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.0/library/sys.html#module-sys). Таблица загруженных модулей (`sys.modules`) и путь поиска модулей (`sys.path`) также раздельны. В новом окружении отсутствует переменная `sys.argv`. В нём есть новые файловые объекты стандартных потоков ввода/вывода `sys.stdin`, `sys.stdout` и `sys.stderr` (однако они ссылаются на те же базовые структуры `FILE` в библиотеке C).5253Возвращаемое значение указывает на первое состояние потока, созданное в новом под-интерпретаторе. Это состояние потока создаётся в текущем состоянии потока. Обратите внимание, что фактический поток не создаётся; см. обсуждение состояний потока ниже. Если создание нового интерпретатора не удалось, возвращается *NULL*; исключение не устанавливается, поскольку состояние исключения хранится в текущем состоянии потока, и текущего состояния потока может не быть. (Как и все другие функции Python/C API, глобальная блокировка интерпретатора должна быть захвачена перед вызовом этой функции и остаётся захваченной при возврате; однако, в отличие от большинства других функций Python/C API, при входе необязательно наличие текущего состояния потока.)5455Модули расширений разделяются между (под-)интерпретаторами следующим образом: при первом импорте конкретного расширения оно инициализируется обычным образом, и создаётся (поверхностная) копия словаря его модуля, которая сохраняется. Когда то же самое расширение импортируется другим (под-)интерпретатором, инициализируется новый модуль и заполняется содержимым этой копии; функция `init` расширения не вызывается. Обратите внимание, что это отличается от ситуации, когда расширение импортируется после полной реинициализации интерпретатора вызовами [`Py_Finalize`](https://python-all.ru/3.0/c-api/init.html#Py_Finalize) и [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize); в этом случае функция `initmodule` расширения *вызывается* снова.5657**Ошибки и предостережения:** Поскольку под-интерпретаторы (и главный интерпретатор) являются частью одного процесса, изоляция между ними не идеальна – например, используя низкоуровневые файловые операции, такие как [`os.close()`](https://python-all.ru/3.0/library/os.html#os.close), они могут (случайно или злонамеренно) влиять на открытые файлы друг друга. Из-за того, как расширения разделяются между (под-)интерпретаторами, некоторые расширения могут работать некорректно; это особенно вероятно, когда расширение использует (статические) глобальные переменные или когда расширение изменяет словарь своего модуля после инициализации. Можно вставлять объекты, созданные в одном под-интерпретаторе, в пространство имён другого под-интерпретатора; это следует делать с большой осторожностью, чтобы избежать совместного использования пользовательских функций, методов, экземпляров или классов между под-интерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут повлиять на словарь загруженных модулей неправильного (под-)интерпретатора. (XXX Это сложно исправимая ошибка, которая будет устранена в одном из будущих релизов.)5859Также учтите, что использование этой функциональности несовместимо с модулями расширений, такими как PyObjC и ctypes, которые используют API `PyGILState_*` (и это заложено в том, как работают функции `PyGILState_*`). Простые вещи могут работать, но странное поведение возможно всегда.6061**\[Py\_EndInterpreter\]void `Py_EndInterpreter`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**6263Уничтожает (под-)интерпретатор, представленный данным состоянием потока. Указанное состояние потока должно быть текущим состоянием потока. Смотрите обсуждение состояний потоков ниже. После возврата вызова текущее состояние потока становится *NULL*. Все состояния потоков, связанные с этим интерпретатором, уничтожаются. (Глобальная блокировка интерпретатора должна быть захвачена перед вызовом этой функции и остаётся захваченной при возврате.) [`Py_Finalize`](https://python-all.ru/3.0/c-api/init.html#Py_Finalize) уничтожит все под-интерпретаторы, которые не были явно уничтожены к этому моменту.6465**\[Py\_SetProgramName\]void `Py_SetProgramName`(wchar\_t *\*name*)**6667Эту функцию следует вызывать до того, как [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize) будет вызвана в первый раз, если она вообще вызывается. Она сообщает интерпретатору значение аргумента `argv[0]` функции `main` программы (преобразованное в широкие символы). Это используется [`Py_GetPath`](https://python-all.ru/3.0/c-api/init.html#Py_GetPath) и некоторыми другими функциями ниже для поиска библиотек времени выполнения Python относительно исполняемого файла интерпретатора. Значение по умолчанию – `'python'`. Аргумент должен указывать на завершающуюся нулём строку широких символов в статической памяти, содержимое которой не изменится за время выполнения программы. Никакой код в интерпретаторе Python не будет изменять содержимое этой памяти.6869**\[Py\_GetProgramName\]wchar\* `Py_GetProgramName`()**7071Возвращает имя программы, установленное с помощью [`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName), или значение по умолчанию. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение.7273**\[Py\_GetPrefix\]wchar\_t\* `Py_GetPrefix`()**7475Возвращает7677*префикс*7879для установленных платформенно-независимых файлов. Он вычисляется по ряду сложных правил на основе имени программы, установленного с помощью8081[`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName)8283, и некоторых переменных окружения; например, если имя программы –8485`'/usr/local/bin/python'`8687, то префикс –8889`'/usr/local'`9091. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это соответствует переменной9293**prefix**9495в корневом9697`Makefile`9899и аргументу100101*--prefix*102103сценария104105**configure**106107во время сборки. Значение доступно в коде Python как108109`sys.prefix`110111. Полезно только в Unix. Смотрите также следующую функцию.112113**\[Py\_GetExecPrefix\]wchar\_t\* `Py_GetExecPrefix`()**114115Возвращает *exec-prefix* для установленных платформенно-*зависимых* файлов. Он вычисляется по ряду сложных правил на основе имени программы, установленного с помощью [`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName), и некоторых переменных окружения; например, если имя программы – `'/usr/local/bin/python'`, то exec-prefix – `'/usr/local'`. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это соответствует переменной **exec\_prefix** в корневом `Makefile` и аргументу *--exec-prefix* сценария **configure** во время сборки. Значение доступно в коде Python как `sys.exec_prefix`. Полезно только в Unix.116117Справочно: exec-prefix отличается от prefix, когда платформозависимые файлы (такие как исполняемые файлы и разделяемые библиотеки) устанавливаются в другое дерево каталогов. В типичной установке платформозависимые файлы могут быть установлены в поддерево `/usr/local/plat`, а платформонезависимые – в `/usr/local`.118119Вообще говоря, платформа – это комбинация семейств аппаратного и программного обеспечения; например, машины Sparc под управлением ОС Solaris 2.x считаются одной платформой, машины Intel под Solaris 2.x – другой, а машины Intel под Linux – третьей. Разные основные версии одной и той же ОС обычно также образуют разные платформы. Операционные системы, отличные от Unix, – это отдельная история; стратегии установки на этих системах настолько различаются, что префикс и exec-prefix не имеют смысла и устанавливаются в пустую строку. Обратите внимание: скомпилированные файлы байт-кода Python не зависят от платформы (но не от версии Python, под которой они были скомпилированы!).120121Системные администраторы знают, как настроить программы **mount** или **automount** для общего доступа к `/usr/local` между платформами, при этом `/usr/local/plat` будет отдельной файловой системой для каждой платформы.122123**\[Py\_GetProgramFullPath\]wchar\_t\* `Py_GetProgramFullPath`()**124125Возвращает полное имя исполняемого файла Python; оно вычисляется как побочный эффект вывода пути поиска модулей по умолчанию из имени программы (установленного с помощью [`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName) выше). Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно в коде Python как `sys.executable`.126127**\[Py\_GetPath\]wchar\_t\* `Py_GetPath`()**128129Возвращает путь поиска модулей по умолчанию; он вычисляется на основе имени программы (установленного с помощью [`Py_SetProgramName`](https://python-all.ru/3.0/c-api/init.html#Py_SetProgramName) выше) и некоторых переменных окружения. Возвращаемая строка состоит из последовательности имён каталогов, разделённых платформенно- зависимым символом-разделителем. Разделителем является `':'` в Unix и Mac OS X, `';'` в Windows. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно в коде Python как список `sys.path`, который можно изменить, чтобы повлиять на дальнейший путь поиска загружаемых модулей.130131**\[Py\_GetVersion\]const char\* `Py_GetVersion`()**132133Возвращает версию данного интерпретатора Python. Это строка, которая выглядит примерно так:134135```c136"3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"137```138139Первое слово (до первого пробела) – это текущая версия Python; первые три символа – старшая и младшая версия, разделённые точкой. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как [`sys.version`](https://python-all.ru/3.0/library/sys.html#sys.version).140141**\[Py\_GetBuildNumber\]const char\* `Py_GetBuildNumber`()**142143Возвращает строку, представляющую ревизию Subversion, из которой была собрана эта исполняемая программа Python. Это число является строкой, поскольку может содержать завершающую букву ‘M’, если Python был собран из дерева исходного кода со смешанными ревизиями.144145**\[Py\_GetPlatform\]const char\* `Py_GetPlatform`()**146147Возвращает идентификатор платформы для текущей платформы. В Unix он формируется из «официального» имени операционной системы, приведённого к нижнему регистру, с добавлением номера старшей версии; например, для Solaris 2.x (также известной как SunOS 5.x) возвращается `'sunos5'`. На Mac OS X – `'darwin'`. В Windows – `'win'`. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как `sys.platform`.148149**\[Py\_GetCopyright\]const char\* `Py_GetCopyright`()**150151Возвращает официальную строку авторских прав для текущей версии Python, например152153`'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`154155Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как `sys.copyright`.156157**\[Py\_GetCompiler\]const char\* `Py_GetCompiler`()**158159Возвращает указание компилятора, использованного для сборки текущей версии Python, в квадратных скобках, например:160161```c162"[GCC 2.7.2.2]"163```164165Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как часть переменной `sys.version`.166167**\[Py\_GetBuildInfo\]const char\* `Py_GetBuildInfo`()**168169Возвращает информацию о номере сборки, дате и времени сборки текущего экземпляра интерпретатора Python, например170171```c172"#67, Aug 1 1997, 22:34:28"173```174175Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как часть переменной `sys.version`.176177**\[PySys\_SetArgv\]void `PySys_SetArgv`(int *argc*, wchar\_t *\*\*argv*)**178179Устанавливает [`sys.argv`](https://python-all.ru/3.0/library/sys.html#sys.argv) на основе *argc* и *argv*. Эти параметры аналогичны тем, что передаются функции `main` программы, с той разницей, что первая запись должна указывать на файл сценария, который будет выполнен, а не на исполняемый файл, содержащий интерпретатор Python. Если сценарий не будет запущен, первая запись в *argv* может быть пустой строкой. Если этой функции не удаётся инициализировать [`sys.argv`](https://python-all.ru/3.0/library/sys.html#sys.argv), фатальная ситуация сигнализируется с помощью [`Py_FatalError`](https://python-all.ru/3.0/c-api/sys.html#Py_FatalError).180181Эта функция также добавляет путь к выполняемому сценарию в начало [`sys.path`](https://python-all.ru/3.0/library/sys.html#sys.path). Если сценарий не выполняется (в случае вызова `python -c` или просто интерактивного интерпретатора), вместо него используется пустая строка.182183**\[Py\_SetPythonHome\]void `Py_SetPythonHome`(char *\*home*)**184185Устанавливает домашний каталог (home), то есть расположение стандартных библиотек Python. Библиотеки ищутся в186187`home/lib/pythonversion`188189и190191`home/lib/pythonversion`192193.194195**\[Py\_GetPythonHome\]char\* `Py_GetPythonHome`()**196197Возвращает домашний каталог (home) по умолчанию, то есть значение, установленное предыдущим вызовом198199[`Py_SetPythonHome`](https://python-all.ru/3.0/c-api/init.html#Py_SetPythonHome)200201, или значение переменной окружения202203[**PYTHONHOME**](https://python-all.ru/3.0/using/cmdline.html#envvar-PYTHONHOME)204205, если она установлена.206207## Состояние потока и глобальная блокировка интерпретатора208209Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python используется глобальная блокировка, которая должна быть захвачена текущим потоком перед тем, как он сможет безопасно обращаться к объектам Python. Без этой блокировки даже простейшие операции могут вызвать проблемы в многопоточной программе: например, когда два потока одновременно увеличивают счётчик ссылок одного и того же объекта, счётчик ссылок может увеличиться только один раз вместо двух.210211Следовательно, существует правило: только поток, захвативший глобальную блокировку интерпретатора, может работать с объектами Python или вызывать функции Python/C API. Для поддержки многопоточных программ на Python интерпретатор регулярно отпускает и снова захватывает блокировку – по умолчанию каждые 100 инструкций байт-кода (это можно изменить с помощью [`sys.setcheckinterval()`](https://python-all.ru/3.0/library/sys.html#sys.setcheckinterval)). Блокировка также отпускается и захватывается вокруг потенциально блокирующих операций ввода-вывода, таких как чтение или запись файла, чтобы другие потоки могли выполняться, пока поток, запросивший ввод-вывод, ожидает завершения операции.212213Интерпретатору Python необходимо хранить некоторую служебную информацию отдельно для каждого потока – для этого используется структура данных, называемая [`PyThreadState`](https://python-all.ru/3.0/c-api/init.html#PyThreadState). Однако существует одна глобальная переменная: указатель на текущую структуру [`PyThreadState`](https://python-all.ru/3.0/c-api/init.html#PyThreadState). Хотя большинство пакетов для работы с потоками имеют способ хранения «глобальных данных потока», внутренняя платформенно-независимая абстракция потоков Python пока этого не поддерживает. Поэтому с текущим состоянием потока необходимо работать явно.214215В большинстве случаев это достаточно просто. Большая часть кода, работающего с глобальной блокировкой интерпретатора, имеет следующую простую структуру:216217```c218Save the thread state in a local variable.219Release the interpreter lock.220...Do some blocking I/O operation...221Reacquire the interpreter lock.222Restore the thread state from the local variable.223```224225Это настолько распространено, что существует пара макросов для упрощения:226227```c228Py_BEGIN_ALLOW_THREADS229...Do some blocking I/O operation...230Py_END_ALLOW_THREADS231```232233Макрос [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_BEGIN_ALLOW_THREADS) открывает новый блок и объявляет скрытую локальную переменную; макрос [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_END_ALLOW_THREADS) закрывает блок. Ещё одно преимущество использования этих двух макросов в том, что когда Python скомпилирован без поддержки потоков, они определяются пустыми, что экономит операции с состоянием потока и блокировкой.234235Когда поддержка потоков включена, указанный выше блок раскрывается в следующий код:236237```c238PyThreadState *_save;239240_save = PyEval_SaveThread();241...Do some blocking I/O operation...242PyEval_RestoreThread(_save);243```244245Используя ещё более низкоуровневые примитивы, можно получить примерно тот же эффект следующим образом:246247```c248PyThreadState *_save;249250_save = PyThreadState_Swap(NULL);251PyEval_ReleaseLock();252...Do some blocking I/O operation...253PyEval_AcquireLock();254PyThreadState_Swap(_save);255```256257Есть некоторые тонкие различия; в частности, [`PyEval_RestoreThread`](https://python-all.ru/3.0/c-api/init.html#PyEval_RestoreThread) сохраняет и восстанавливает значение глобальной переменной `errno`, поскольку манипуляции с блокировкой не гарантируют, что `errno` останется нетронутой. Кроме того, когда поддержка потоков отключена, [`PyEval_SaveThread`](https://python-all.ru/3.0/c-api/init.html#PyEval_SaveThread) и [`PyEval_RestoreThread`](https://python-all.ru/3.0/c-api/init.html#PyEval_RestoreThread) не работают с блокировкой; в этом случае [`PyEval_ReleaseLock`](https://python-all.ru/3.0/c-api/init.html#PyEval_ReleaseLock) и [`PyEval_AcquireLock`](https://python-all.ru/3.0/c-api/init.html#PyEval_AcquireLock) недоступны. Это сделано для того, чтобы динамически загружаемые расширения, скомпилированные с поддержкой потоков, могли быть загружены интерпретатором, скомпилированным без поддержки потоков.258259Глобальная блокировка интерпретатора используется для защиты указателя на текущее состояние потока. При отпускании блокировки и сохранении состояния потока указатель на текущее состояние потока должен быть получен до того, как блокировка будет отпущена (поскольку другой поток может немедленно захватить блокировку и сохранить своё собственное состояние потока в глобальной переменной). И наоборот, при захвате блокировки и восстановлении состояния потока блокировка должна быть захвачена до сохранения указателя на состояние потока.260261Зачем я так подробно это описываю? Потому что когда потоки создаются из C, у них нет глобальной блокировки интерпретатора, а также для них нет структуры данных состояния потока. Такие потоки должны инициализировать себя: сначала создать структуру данных состояния потока, затем захватить блокировку и, наконец, сохранить указатель на своё состояние потока, прежде чем они смогут начать использовать Python/C API. Когда они завершают работу, они должны сбросить указатель на состояние потока, отпустить блокировку и, наконец, освободить свою структуру данных состояния потока.262263Потоки могут воспользоваться функциями `PyGILState_*`, чтобы выполнить всё вышеописанное автоматически. Типичный способ вызова Python из потока C теперь выглядит так:264265```c266PyGILState_STATE gstate;267gstate = PyGILState_Ensure();268269/* Выполнить действия Python здесь. */270result = CallSomeFunction();271/* результат вычисления */272273/* Освободить поток. После этой точки API Python не допускается. */274PyGILState_Release(gstate);275```276277Обратите внимание, что функции `PyGILState_*` предполагают наличие только одного глобального интерпретатора (создаваемого автоматически с помощью [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize)). Python по-прежнему поддерживает создание дополнительных интерпретаторов (с помощью [`Py_NewInterpreter`](https://python-all.ru/3.0/c-api/init.html#Py_NewInterpreter)), но смешивание нескольких интерпретаторов и API `PyGILState_*` не поддерживается.278279**\[PyInterpreterState\]`PyInterpreterState`**280281Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, разделяют администрирование модулей и несколько других внутренних элементов. В этой структуре нет открытых членов.282283Потоки, принадлежащие разным интерпретаторам, изначально не разделяют ничего, кроме состояния процесса, такого как доступная память, открытые файловые дескрипторы и т.п. Глобальная блокировка интерпретатора также разделяется всеми потоками, независимо от того, какому интерпретатору они принадлежат.284285**\[PyThreadState\]`PyThreadState`**286287Эта структура данных представляет состояние одного потока. Единственная открытая (public) переменная-член –288289[`PyInterpreterState *`](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState)290291`interp`292293, которая указывает на состояние интерпретатора этого потока.294295**\[PyEval\_InitThreads\]void `PyEval_InitThreads`()**296297Инициализирует и захватывает глобальную блокировку интерпретатора. Должна вызываться в главном потоке перед созданием второго потока или выполнением любых других потоковых операций, таких как [`PyEval_ReleaseLock`](https://python-all.ru/3.0/c-api/init.html#PyEval_ReleaseLock) или `PyEval_ReleaseThread(tstate)`. Её не нужно вызывать перед [`PyEval_SaveThread`](https://python-all.ru/3.0/c-api/init.html#PyEval_SaveThread) или [`PyEval_RestoreThread`](https://python-all.ru/3.0/c-api/init.html#PyEval_RestoreThread).298299При повторном вызове эта функция ничего не делает. Её безопасно вызывать до вызова [`Py_Initialize`](https://python-all.ru/3.0/c-api/init.html#Py_Initialize).300301Когда существует только главный поток, операции с блокировкой не нужны. Это обычная ситуация (большинство программ Python не используют потоки), и операции с блокировкой немного замедляют интерпретатор. Поэтому блокировка изначально не создаётся. Эта ситуация эквивалентна захваченной блокировке: когда есть только один поток, все обращения к объектам безопасны. Поэтому, когда эта функция инициализирует блокировку, она также её захватывает. Перед тем как модуль Python [`_thread`](https://python-all.ru/3.0/library/_thread.html#module-_thread) создаёт новый поток, зная, что либо у него уже есть блокировка, либо блокировка ещё не создана, он вызывает [`PyEval_InitThreads`](https://python-all.ru/3.0/c-api/init.html#PyEval_InitThreads). Когда этот вызов возвращается, гарантируется, что блокировка создана и что вызывающий поток её захватил.302303**Не**безопасно вызывать эту функцию, когда неизвестно, какой поток (если таковой есть) в данный момент удерживает глобальную блокировку интерпретатора.304305Эта функция недоступна, если поддержка потоков отключена на этапе компиляции.306307**\[PyEval\_ThreadsInitialized\]int `PyEval_ThreadsInitialized`()**308309Возвращает ненулевое значение, если310311[`PyEval_InitThreads`](https://python-all.ru/3.0/c-api/init.html#PyEval_InitThreads)312313была вызвана. Эту функцию можно вызывать, не удерживая блокировку, и поэтому её можно использовать для избегания вызовов API блокировки при однопоточном выполнении. Эта функция недоступна, если поддержка потоков отключена во время компиляции.314315**\[PyEval\_AcquireLock\]void `PyEval_AcquireLock`()**316317Захватывает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее. Если этот поток уже владеет блокировкой, возникнет взаимная блокировка. Эта функция недоступна, если поддержка потоков отключена при компиляции.318319**\[PyEval\_ReleaseLock\]void `PyEval_ReleaseLock`()**320321Освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее. Эта функция недоступна, если поддержка потоков отключена при компиляции.322323**\[PyEval\_AcquireThread\]void `PyEval_AcquireThread`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**324325Захватывает глобальную блокировку интерпретатора и устанавливает текущее состояние потока в326327*tstate*328329, которое не должно быть330331*NULL*332333. Блокировка должна быть создана ранее. Если этот поток уже владеет блокировкой, возникнет взаимная блокировка. Эта функция недоступна, если поддержка потоков отключена при компиляции.334335**\[PyEval\_ReleaseThread\]void `PyEval_ReleaseThread`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**336337Сбрасывает текущее состояние потока в338339*NULL*340341и освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и должна удерживаться текущим потоком. Аргумент342343*tstate*344345, который не должен быть346347*NULL*348349, используется только для проверки, что он представляет текущее состояние потока – если нет, сообщается о фатальной ошибке. Эта функция недоступна, если поддержка потоков отключена при компиляции.350351**\[PyEval\_SaveThread\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `PyEval_SaveThread`()**352353Освобождает блокировку интерпретатора (если она была создана и поддержка потоков включена) и сбрасывает состояние потока в354355*NULL*356357, возвращая предыдущее состояние потока (которое не является358359*NULL*360361). Если блокировка была создана, текущий поток должен был её захватить. (Эта функция доступна, даже если поддержка потоков отключена при компиляции.)362363**\[PyEval\_RestoreThread\]void `PyEval_RestoreThread`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**364365Захватывает блокировку интерпретатора (если она была создана и поддержка потоков включена) и устанавливает состояние потока в366367*tstate*368369, которое не должно быть370371*NULL*372373. Если блокировка была создана, текущий поток не должен был её захватить, иначе возникнет взаимная блокировка. (Эта функция доступна, даже если поддержка потоков отключена при компиляции.)374375**\[PyEval\_ReInitThreads\]void `PyEval_ReInitThreads`()**376377Эта функция вызывается из378379[`PyOS_AfterFork`](https://python-all.ru/3.0/c-api/sys.html#PyOS_AfterFork)380381, чтобы гарантировать, что вновь созданные дочерние процессы не удерживают блокировки, относящиеся к потокам, которые не выполняются в дочернем процессе.382383Следующие макросы обычно используются без точки с запятой в конце; примеры использования можно найти в дистрибутиве исходного кода Python.384385**\[Py\_BEGIN\_ALLOW\_THREADS\]`Py_BEGIN_ALLOW_THREADS`**386387Этот макрос раскрывается в388389`{ PyThreadState *_save; _save = PyEval_SaveThread();`390391. Обратите внимание, что он содержит открывающую фигурную скобку; он должен быть уравновешен последующим макросом392393[`Py_END_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_END_ALLOW_THREADS)394395. См. выше обсуждение этого макроса. Ничего не делает, если поддержка потоков отключена во время компиляции.396397**\[Py\_END\_ALLOW\_THREADS\]`Py_END_ALLOW_THREADS`**398399Этот макрос раскрывается в400401`PyEval_RestoreThread(_save); }`402403. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть уравновешен предшествующим макросом404405[`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_BEGIN_ALLOW_THREADS)406407. См. выше обсуждение этого макроса. Ничего не делает, если поддержка потоков отключена во время компиляции.408409**\[Py\_BLOCK\_THREADS\]`Py_BLOCK_THREADS`**410411Этот макрос раскрывается в412413`PyEval_RestoreThread(_save);`414415: он эквивалентен416417[`Py_END_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_END_ALLOW_THREADS)418419без закрывающей фигурной скобки. Он не выполняет никаких действий, если поддержка потоков отключена на этапе компиляции.420421**\[Py\_UNBLOCK\_THREADS\]`Py_UNBLOCK_THREADS`**422423Этот макрос раскрывается в424425`_save = PyEval_SaveThread();`426427: он эквивалентен428429[`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_BEGIN_ALLOW_THREADS)430431без открывающей фигурной скобки и объявления переменной. Он не выполняет никаких действий, если поддержка потоков отключена на этапе компиляции.432433Все следующие функции доступны только при включённой поддержке потоков на этапе компиляции и должны вызываться только тогда, когда блокировка интерпретатора была создана.434435**\[PyInterpreterState\_New\][PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_New`()**436437Создаёт новый объект состояния интерпретатора. Блокировку интерпретатора не обязательно удерживать, но её можно удерживать, если необходимо сериализовать вызовы этой функции.438439**\[PyInterpreterState\_Clear\]void `PyInterpreterState_Clear`([PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState) *\*interp*)**440441Сбрасывает всю информацию в объекте состояния интерпретатора. Блокировка интерпретатора должна удерживаться.442443**\[PyInterpreterState\_Delete\]void `PyInterpreterState_Delete`([PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState) *\*interp*)**444445Уничтожает объект состояния интерпретатора. Блокировку интерпретатора не обязательно удерживать. Состояние интерпретатора должно быть сброшено предыдущим вызовом446447[`PyInterpreterState_Clear`](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState_Clear)448449.450451**\[PyThreadState\_New\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `PyThreadState_New`([PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState) *\*interp*)**452453Создаёт новый объект состояния потока, принадлежащий данному объекту интерпретатора. Блокировку интерпретатора не обязательно удерживать, но её можно удерживать, если необходимо сериализовать вызовы этой функции.454455**\[PyThreadState\_Clear\]void `PyThreadState_Clear`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**456457Сбрасывает всю информацию в объекте состояния потока. Блокировка интерпретатора должна удерживаться.458459**\[PyThreadState\_Delete\]void `PyThreadState_Delete`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**460461Уничтожает объект состояния потока. Блокировку интерпретатора не обязательно удерживать. Состояние потока должно быть сброшено предыдущим вызовом462463[`PyThreadState_Clear`](https://python-all.ru/3.0/c-api/init.html#PyThreadState_Clear)464465.466467**\[PyThreadState\_Get\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `PyThreadState_Get`()**468469Возвращает текущее состояние потока. Блокировка интерпретатора должна удерживаться. Если текущее состояние потока равно470471*NULL*472473, это приводит к фатальной ошибке (так что вызывающему не нужно проверять на474475*NULL*476477).478479**\[PyThreadState\_Swap\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `PyThreadState_Swap`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**480481Заменяет текущее состояние потока на состояние, заданное аргументом482483*tstate*484485, который может быть486487*NULL*488489. Должна быть захвачена блокировка интерпретатора.490491**\[PyThreadState\_GetDict\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* `PyThreadState_GetDict`()**492493*Возвращаемое значение: заимствованная ссылка.*494495Возвращает словарь, в котором расширения могут хранить информацию о состоянии, специфичном для потока. Каждое расширение должно использовать уникальный ключ для хранения состояния в словаре. Эту функцию можно вызывать, даже если текущее состояние потока недоступно. Если эта функция возвращает *NULL*, исключение не было возбуждено, и вызывающий код должен считать, что текущее состояние потока недоступно.496497**\[PyThreadState\_SetAsyncExc\]int `PyThreadState_SetAsyncExc`(long *id*, [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*exc*)**498499Асинхронно возбуждает исключение в потоке. Аргумент500501*id*502503– это идентификатор потока целевого потока;504505*exc*506507– объект исключения, которое нужно возбудить. Эта функция не похищает никаких ссылок на508509*exc*510511. Чтобы предотвратить наивное злоупотребление, вы должны написать собственное расширение C для её вызова. Должна вызываться с захваченным GIL. Возвращает количество изменённых состояний потока; обычно это единица, но будет нулём, если идентификатор потока не найден. Если512513*exc*514515равно516517`NULL`518519, то ожидающее исключение (если есть) для потока очищается. Эта функция не возбуждает исключений.520521**\[PyGILState\_Ensure\]PyGILState\_STATE `PyGILState_Ensure`()**522523Гарантирует, что текущий поток готов вызывать C API Python независимо от текущего состояния Python или его блокировки потоков. Этот вызов можно повторять сколько угодно раз, если каждый вызов сопровождается вызовом [`PyGILState_Release`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Release). В целом, между вызовами [`PyGILState_Ensure`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Ensure) и [`PyGILState_Release`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Release) можно использовать другие потоковые API, при условии, что состояние потока будет восстановлено до предыдущего состояния перед вызовом Release(). Например, допустимо обычное использование макросов [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_BEGIN_ALLOW_THREADS) и [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.0/c-api/init.html#Py_END_ALLOW_THREADS).524525Возвращаемое значение – это непрозрачный «дескриптор» состояния потока, которое было при вызове [`PyGILState_Ensure`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Ensure). Его необходимо передать в [`PyGILState_Release`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Release), чтобы Python остался в том же состоянии. Несмотря на то, что рекурсивные вызовы разрешены, эти дескрипторы *нельзя* совместно использовать – каждый уникальный вызов [`PyGILState_Ensure`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Ensure) должен сохранить дескриптор для своего вызова [`PyGILState_Release`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Release).526527При возврате из функции текущий поток будет удерживать GIL. Сбой является фатальной ошибкой.528529**\[PyGILState\_Release\]void `PyGILState_Release`(PyGILState\_STATE)**530531Освобождает все ранее захваченные ресурсы. После этого вызова состояние Python будет таким же, как и до соответствующего вызова [`PyGILState_Ensure`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Ensure) (однако обычно это состояние будет неизвестно вызывающему, поэтому и используется API GILState).532533Каждый вызов [`PyGILState_Ensure`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Ensure) должен сопровождаться вызовом [`PyGILState_Release`](https://python-all.ru/3.0/c-api/init.html#PyGILState_Release) в том же потоке.534535## Профилирование и трассировка536537Интерпретатор Python предоставляет низкоуровневую поддержку для подключения средств профилирования и трассировки выполнения. Они используются в инструментах профилирования, отладки и анализа покрытия.538539Этот C-интерфейс позволяет коду профилирования или трассировки избежать накладных расходов на вызов через вызываемые объекты уровня Python, выполняя вместо этого прямой вызов C-функции. Основные характеристики механизма не изменились; интерфейс позволяет устанавливать функции трассировки для каждого потока, а базовые события, сообщаемые функции трассировки, такие же, как и в предыдущих версиях для функций трассировки уровня Python.540541**\[Py\_tracefunc\]int `(*Py_tracefunc)`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*, PyFrameObject *\*frame*, int *what*, [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*arg*)**542543Тип трассировочной функции, регистрируемой с помощью [`PyEval_SetProfile`](https://python-all.ru/3.0/c-api/init.html#PyEval_SetProfile) и [`PyEval_SetTrace`](https://python-all.ru/3.0/c-api/init.html#PyEval_SetTrace). Первый параметр – это объект, переданный в функцию регистрации как *obj*; *frame* – это объект фрейма, к которому относится событие; *what* – одна из констант: [`PyTrace_CALL`](https://python-all.ru/3.0/c-api/init.html#PyTrace_CALL), [`PyTrace_EXCEPTION`](https://python-all.ru/3.0/c-api/init.html#PyTrace_EXCEPTION), [`PyTrace_LINE`](https://python-all.ru/3.0/c-api/init.html#PyTrace_LINE), [`PyTrace_RETURN`](https://python-all.ru/3.0/c-api/init.html#PyTrace_RETURN), [`PyTrace_C_CALL`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_CALL), [`PyTrace_C_EXCEPTION`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_EXCEPTION) или [`PyTrace_C_RETURN`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_RETURN), а *arg* зависит от значения *what*:544545| Значение *what* | Смысл *arg* |546| --- | --- |547| [`PyTrace_CALL`](https://python-all.ru/3.0/c-api/init.html#PyTrace_CALL) | Всегда *NULL*. |548| [`PyTrace_EXCEPTION`](https://python-all.ru/3.0/c-api/init.html#PyTrace_EXCEPTION) | Информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/3.0/library/sys.html#sys.exc_info). |549| [`PyTrace_LINE`](https://python-all.ru/3.0/c-api/init.html#PyTrace_LINE) | Всегда *NULL*. |550| [`PyTrace_RETURN`](https://python-all.ru/3.0/c-api/init.html#PyTrace_RETURN) | Значение, возвращаемое вызывающему. |551| [`PyTrace_C_CALL`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_CALL) | Имя вызываемой функции. |552| [`PyTrace_C_EXCEPTION`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_EXCEPTION) | Всегда *NULL*. |553| [`PyTrace_C_RETURN`](https://python-all.ru/3.0/c-api/init.html#PyTrace_C_RETURN) | Всегда *NULL*. |554555**\[PyTrace\_CALL\]int `PyTrace_CALL`**556557Значение параметра558559*what*560561функции562563[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)564565, когда сообщается о новом вызове функции или метода, или о новом входе в генератор. Обратите внимание, что создание итератора для функции-генератора не сообщается, поскольку нет передачи управления байт-коду Python в соответствующем фрейме.566567**\[PyTrace\_EXCEPTION\]int `PyTrace_EXCEPTION`**568569Значение параметра570571*what*572573функции574575[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)576577, когда возникло исключение. Функция обратного вызова вызывается с этим значением для578579*what*580581после обработки любого байт-кода, после которого исключение устанавливается в выполняемом фрейме. В результате, когда распространение исключения вызывает разворачивание стека Python, обратный вызов вызывается при возврате в каждый фрейм по мере распространения исключения. Только функции трассировки получают эти события; профилировщику они не нужны.582583**\[PyTrace\_LINE\]int `PyTrace_LINE`**584585Значение, передаваемое в качестве параметра586587*what*588589в трассировочную функцию (но не в профилирующую функцию), когда сообщается о событии номера строки.590591**\[PyTrace\_RETURN\]int `PyTrace_RETURN`**592593Значение параметра594595*what*596597функций598599[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)600601, когда вызов возвращается без распространения исключения.602603**\[PyTrace\_C\_CALL\]int `PyTrace_C_CALL`**604605Значение параметра606607*what*608609функций610611[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)612613, когда функция на C собирается быть вызванной.614615**\[PyTrace\_C\_EXCEPTION\]int `PyTrace_C_EXCEPTION`**616617Значение параметра618619*what*620621для функций622623[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)624625, когда C-функция вызвала исключение.626627**\[PyTrace\_C\_RETURN\]int `PyTrace_C_RETURN`**628629Значение параметра630631*what*632633функций634635[`Py_tracefunc`](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc)636637, когда функция на C вернулась.638639**\[PyEval\_SetProfile\]void `PyEval_SetProfile`([Py\_tracefunc](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc) *func*, [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*)**640641Устанавливает функцию профилировщика в642643*func*644645. Параметр646647*obj*648649передаётся функции в качестве первого аргумента и может быть любым объектом Python или650651*NULL*652653. Если функции профилировщика требуется поддерживать состояние, использование разных значений654655*obj*656657для каждого потока предоставляет удобное и потокобезопасное место для его хранения. Функция профилировщика вызывается для всех отслеживаемых событий, кроме событий с номерами строк.658659**\[PyEval\_SetTrace\]void `PyEval_SetTrace`([Py\_tracefunc](https://python-all.ru/3.0/c-api/init.html#Py_tracefunc) *func*, [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*)**660661Устанавливает трассирующую функцию в662663*func*664665. Эта функция аналогична666667[`PyEval_SetProfile`](https://python-all.ru/3.0/c-api/init.html#PyEval_SetProfile)668669, за исключением того, что трассирующая функция получает события номеров строк.670671**\[PyEval\_GetCallStats\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* `PyEval_GetCallStats`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*self*)**672673Возвращает кортеж счётчиков вызовов функций. Для позиций в кортеже определены константы:674675| Имя | Значение |676| --- | --- |677| `PCALL_ALL` | 0 |678| `PCALL_FUNCTION` | 1 |679| `PCALL_FAST_FUNCTION` | 2 |680| `PCALL_FASTER_FUNCTION` | 3 |681| `PCALL_METHOD` | 4 |682| `PCALL_BOUND_METHOD` | 5 |683| `PCALL_CFUNCTION` | 6 |684| `PCALL_TYPE` | 7 |685| `PCALL_GENERATOR` | 8 |686| `PCALL_OTHER` | 9 |687| `PCALL_POP` | 10 |688689`PCALL_FAST_FUNCTION` означает, что создавать кортеж аргументов не требуется. `PCALL_FASTER_FUNCTION` означает, что используется код быстрой настройки фрейма.690691Если есть вызов метода, который можно оптимизировать, изменив кортеж аргументов и вызвав функцию напрямую, он записывается дважды.692693Эта функция доступна только при компиляции Python с определённым `CALL_PROFILE`.694695## Поддержка расширенного отладчика696697Эти функции предназначены только для использования расширенными инструментами отладки.698699**\[PyInterpreterState\_Head\][PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_Head`()**700701Возвращает объект состояния интерпретатора, находящийся в начале списка всех таких объектов.702703**\[PyInterpreterState\_Next\][PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_Next`([PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState) *\*interp*)**704705Возвращает следующий объект состояния интерпретатора после706707*interp*708709из списка всех таких объектов.710711**\[PyInterpreterState\_ThreadHead\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) \* `PyInterpreterState_ThreadHead`([PyInterpreterState](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState) *\*interp*)**712713Возвращает указатель на первый объект714715[`PyThreadState`](https://python-all.ru/3.0/c-api/init.html#PyThreadState)716717в списке\\nпотоков, связанных с интерпретатором718719*interp*720721.722723**\[PyThreadState\_Next\][PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState)\* `PyThreadState_Next`([PyThreadState](https://python-all.ru/3.0/c-api/init.html#PyThreadState) *\*tstate*)**724725Возвращает следующий объект состояния потока после726727*tstate*728729из списка всех таких объектов, принадлежащих одному и тому же объекту730731[`PyInterpreterState`](https://python-all.ru/3.0/c-api/init.html#PyInterpreterState)732733.734