init.md
1> **Источник:** https://python-all.ru/3.1/c-api/init.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Инициализация, финализация и потоки89## Инициализация и завершение работы интерпретатора1011**void `Py_Initialize`()**1213Инициализирует интерпретатор Python. В приложении, встраивающем Python, эта функция должна вызываться до использования любых других функций Python/C API; за исключением [`Py_SetProgramName()`](https://python-all.ru/3.1/c-api/init.html#Py_SetProgramName), [`PyEval_InitThreads()`](https://python-all.ru/3.1/c-api/init.html#PyEval_InitThreads), [`PyEval_ReleaseLock()`](https://python-all.ru/3.1/c-api/init.html#PyEval_ReleaseLock) и [`PyEval_AcquireLock()`](https://python-all.ru/3.1/c-api/init.html#PyEval_AcquireLock). Она инициализирует таблицу загруженных модулей (`sys.modules`) и создаёт фундаментальные модули [`builtins`](https://python-all.ru/3.1/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.1/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.1/library/sys.html#module-sys). Также инициализируется путь поиска модулей (`sys.path`). Она не устанавливает `sys.argv`; для этого используйте [`PySys_SetArgvEx()`](https://python-all.ru/3.1/c-api/init.html#PySys_SetArgvEx). При повторном вызове без предварительного вызова [`Py_Finalize()`](https://python-all.ru/3.1/c-api/init.html#Py_Finalize) эта функция ничего не делает. Возвращаемое значение отсутствует; при ошибке инициализации происходит фатальная ошибка.1415**void `Py_InitializeEx`(int *initsigs*)**1617Эта функция работает как1819[`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize)2021, если2223*initsigs*2425равно 1. Если2627*initsigs*2829равно 0, она пропускает инициализацию регистрации обработчиков сигналов, что может быть полезно при встраивании Python.3031**int `Py_IsInitialized`()**3233Возвращает true (ненулевое значение), если интерпретатор Python был инициализирован, и false (ноль) в противном случае. После вызова3435[`Py_Finalize()`](https://python-all.ru/3.1/c-api/init.html#Py_Finalize)3637возвращает false до тех пор, пока снова не будет вызвана3839[`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize)4041.4243**void `Py_Finalize`()**4445Отменяет всю инициализацию, выполненную [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize) и последующее использование функций Python/C API, и уничтожает все под-интерпретаторы (см. [`Py_NewInterpreter()`](https://python-all.ru/3.1/c-api/init.html#Py_NewInterpreter) ниже), которые были созданы и ещё не уничтожены после последнего вызова [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize). В идеале освобождает всю память, выделенную интерпретатором Python. Повторный вызов (без предварительного повторного вызова [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize)) ничего не делает. Возвращаемого значения нет; ошибки при финализации игнорируются.4647Эта функция предусмотрена по ряду причин. Встраивающее приложение может захотеть перезапустить Python без перезапуска самого приложения. Приложение, загрузившее интерпретатор Python из динамически загружаемой библиотеки (или DLL), может захотеть освободить всю память, выделенную Python, перед выгрузкой DLL. В процессе поиска утечек памяти в приложении разработчик может захотеть освободить всю память, выделенную Python, перед выходом из приложения.4849**Ошибки и предостережения:** Уничтожение модулей и объектов в модулях происходит в случайном порядке; это может привести к сбоям деструкторов (методов [`__del__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__del__)), если они зависят от других объектов (даже функций) или модулей. Динамически загружаемые модули расширений, загруженные Python, не выгружаются. Небольшие объёмы памяти, выделенные интерпретатором Python, могут не освобождаться (если вы обнаружите утечку, сообщите о ней). Память, связанная циклическими ссылками между объектами, не освобождается. Некоторый объём памяти, выделенный модулями расширений, может не освободиться. Некоторые расширения могут работать неправильно, если их процедура инициализации вызывается более одного раза; это может произойти, если приложение вызывает [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize) и [`Py_Finalize()`](https://python-all.ru/3.1/c-api/init.html#Py_Finalize) более одного раза.5051## Общепроцессные параметры5253**void `Py_SetProgramName`(wchar\_t *\*name*)**5455Эту функцию следует вызывать перед первым вызовом [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize), если она вообще вызывается. Она сообщает интерпретатору значение аргумента `argv[0]` для функции `main()` программы (преобразованное в широкие символы). Это используется [`Py_GetPath()`](https://python-all.ru/3.1/c-api/init.html#Py_GetPath) и некоторыми другими функциями ниже для поиска библиотек времени выполнения Python относительно исполняемого файла интерпретатора. Значение по умолчанию – `'python'`. Аргумент должен указывать на широкую символьную строку с завершающим нулём в статической памяти, содержимое которой не изменится за время выполнения программы. Никакой код в интерпретаторе Python не изменит содержимое этой памяти.5657**wchar\* `Py_GetProgramName`()**5859Возвращает имя программы, установленное с помощью [`Py_SetProgramName()`](https://python-all.ru/3.1/c-api/init.html#Py_SetProgramName), или значение по умолчанию. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение.6061**wchar\_t\* `Py_GetPrefix`()**6263Возвращает6465*префикс*6667для установленных платформонезависимых файлов. Он вычисляется с помощью ряда сложных правил на основе имени программы, заданного с помощью6869[`Py_SetProgramName()`](https://python-all.ru/3.1/c-api/init.html#Py_SetProgramName)7071, и некоторых переменных окружения; например, если имя программы –7273`'/usr/local/bin/python'`7475, то префикс –7677`'/usr/local'`7879. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это соответствует переменной8081**prefix**8283в корневом8485`Makefile`8687и аргументу8889*--prefix*9091сценария9293**configure**9495во время сборки. Это значение доступно в коде Python как9697`sys.prefix`9899. Полезно только в Unix. Смотрите также следующую функцию.100101**wchar\_t\* `Py_GetExecPrefix`()**102103Возвращает *exec-prefix* для установленных *зависимых от платформы* файлов. Он вычисляется с помощью ряда сложных правил на основе имени программы, заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.1/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.104105Справочно: exec-prefix отличается от prefix, когда платформозависимые файлы (такие как исполняемые файлы и разделяемые библиотеки) устанавливаются в другое дерево каталогов. В типичной установке платформозависимые файлы могут быть установлены в поддерево `/usr/local/plat`, а платформонезависимые – в `/usr/local`.106107Вообще говоря, платформа – это комбинация семейств аппаратного и программного обеспечения; например, машины Sparc под управлением ОС Solaris 2.x считаются одной платформой, машины Intel под Solaris 2.x – другой, а машины Intel под Linux – третьей. Разные основные версии одной и той же ОС обычно также образуют разные платформы. Операционные системы, отличные от Unix, – это отдельная история; стратегии установки на этих системах настолько различаются, что префикс и exec-prefix не имеют смысла и устанавливаются в пустую строку. Обратите внимание: скомпилированные файлы байт-кода Python не зависят от платформы (но не от версии Python, под которой они были скомпилированы!).108109Системные администраторы знают, как настроить программы **mount** или **automount** для общего доступа к `/usr/local` между платформами, при этом `/usr/local/plat` будет отдельной файловой системой для каждой платформы.110111**wchar\_t\* `Py_GetProgramFullPath`()**112113Возвращает полное имя исполняемого файла Python; оно вычисляется как побочный эффект вывода пути поиска модулей по умолчанию из имени программы (заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.1/c-api/init.html#Py_SetProgramName) выше). Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Значение доступно в коде Python как `sys.executable`.114115**wchar\_t\* `Py_GetPath`()**116117Возвращает путь поиска модулей по умолчанию; он вычисляется на основе имени программы (заданного с помощью [`Py_SetProgramName()`](https://python-all.ru/3.1/c-api/init.html#Py_SetProgramName) выше) и некоторых переменных окружения. Возвращаемая строка состоит из последовательности имён каталогов, разделённых символом-разделителем, зависящим от платформы. Символ-разделитель – `':'` на Unix и Mac OS X, `';'` на Windows. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Список [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) инициализируется этим значением при запуске интерпретатора; он может быть (и обычно) изменён позже для изменения пути поиска при загрузке модулей.118119**const char\* `Py_GetVersion`()**120121Возвращает версию данного интерпретатора Python. Это строка, которая выглядит примерно так:122123```c124"3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"125```126127Первое слово (до первого пробела) – это текущая версия Python; первые три символа – старшая и младшая версия, разделённые точкой. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как [`sys.version`](https://python-all.ru/3.1/library/sys.html#sys.version).128129**const char\* `Py_GetPlatform`()**130131Возвращает идентификатор платформы для текущей платформы. В Unix он формируется из «официального» имени операционной системы, приведённого к нижнему регистру, с добавлением номера старшей версии; например, для Solaris 2.x (также известной как SunOS 5.x) возвращается `'sunos5'`. На Mac OS X – `'darwin'`. В Windows – `'win'`. Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как `sys.platform`.132133**const char\* `Py_GetCopyright`()**134135Возвращает официальную строку авторских прав для текущей версии Python, например136137`'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`138139Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как `sys.copyright`.140141**const char\* `Py_GetCompiler`()**142143Возвращает указание компилятора, использованного для сборки текущей версии Python, в квадратных скобках, например:144145```c146"[GCC 2.7.2.2]"147```148149Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как часть переменной `sys.version`.150151**const char\* `Py_GetBuildInfo`()**152153Возвращает информацию о номере сборки, дате и времени сборки текущего экземпляра интерпретатора Python, например154155```c156"#67, Aug 1 1997, 22:34:28"157```158159Возвращаемая строка указывает на статическую память; вызывающий код не должен изменять её значение. Это значение доступно в коде Python как часть переменной `sys.version`.160161**void `PySys_SetArgvEx`(int *argc*, wchar\_t *\*\*argv*, int *updatepath*)**162163Устанавливает [`sys.argv`](https://python-all.ru/3.1/library/sys.html#sys.argv) на основе *argc* и *argv*. Эти параметры аналогичны тем, что передаются в функцию `main()` программы, с той разницей, что первый элемент должен указывать на исполняемый файл скрипта, а не на исполняемый файл, в который встроен интерпретатор Python. Если запускаемый скрипт отсутствует, первый элемент в *argv* может быть пустой строкой. Если эта функция не сможет инициализировать [`sys.argv`](https://python-all.ru/3.1/library/sys.html#sys.argv), сигнализируется фатальная ошибка с помощью [`Py_FatalError()`](https://python-all.ru/3.1/c-api/sys.html#Py_FatalError).164165Если *updatepath* равен нулю, функция делает только это. Если *updatepath* не равен нулю, функция также изменяет [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) согласно следующему алгоритму:166167- Если в `argv[0]` передано имя существующего скрипта, в начало [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) добавляется абсолютный путь к каталогу, где находится этот скрипт.168- В противном случае (то есть если *argc* равно 0 или `argv[0]` не указывает на существующий файл), в начало [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) добавляется пустая строка, что равносильно добавлению текущего рабочего каталога (`"."`).169170> **Примечание**171>172> Приложениям, встраивающим интерпретатор Python для целей, отличных от выполнения одного скрипта, рекомендуется передавать 0 в качестве *updatepath* и при необходимости изменять [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) самостоятельно. См. [CVE-2008-5983](https://python-all.ru/3.1/c-api/init.html).173>174> В версиях до 3.1.3 того же эффекта можно достичь, вручную удалив первый элемент [`sys.path`](https://python-all.ru/3.1/library/sys.html#sys.path) после вызова [`PySys_SetArgv()`](https://python-all.ru/3.1/c-api/init.html#PySys_SetArgv), например с помощью:175>176> ```c177> PyRun_SimpleString("import sys; sys.path.pop(0)\n");178> ```179180Новое в версии 3.1.3.181182**void `PySys_SetArgv`(int *argc*, wchar\_t *\*\*argv*)**183184Эта функция работает как185186[`PySys_SetArgvEx()`](https://python-all.ru/3.1/c-api/init.html#PySys_SetArgvEx)187188, при этом189190*updatepath*191192устанавливается в 1.193194**void `Py_SetPythonHome`(wchar\_t *\*home*)**195196Устанавливает домашний каталог по умолчанию, то есть расположение стандартных библиотек Python. Смотрите [**PYTHONHOME**](https://python-all.ru/3.1/using/cmdline.html#envvar-PYTHONHOME) для описания значения строки аргумента.197198Аргумент должен указывать на строку символов, завершающуюся нулём, в статической памяти, содержимое которой не будет изменяться в течение всего времени выполнения программы. Никакой код в интерпретаторе Python не будет менять содержимое этой памяти.199200**w\_char\* `Py_GetPythonHome`()**201202Возвращает домашний каталог по умолчанию, то есть значение, установленное предыдущим вызовом203204[`Py_SetPythonHome()`](https://python-all.ru/3.1/c-api/init.html#Py_SetPythonHome)205206, или значение переменной окружения207208[**PYTHONHOME**](https://python-all.ru/3.1/using/cmdline.html#envvar-PYTHONHOME)209210, если она установлена.211212## Состояние потока и глобальная блокировка интерпретатора213214Интерпретатор Python не является полностью потокобезопасным. Для поддержки многопоточных программ на Python существует глобальная блокировка, называемая [*глобальной блокировкой интерпретатора*](https://python-all.ru/3.1/glossary.html#term-global-interpreter-lock) или [*GIL*](https://python-all.ru/3.1/glossary.html#term-gil), которую текущий поток должен удерживать перед тем, как безопасно обращаться к объектам Python. Без этой блокировки даже простейшие операции могут вызывать проблемы в многопоточной программе: например, когда два потока одновременно увеличивают счётчик ссылок одного и того же объекта, счётчик может в итоге увеличиться только один раз вместо двух.215216Следовательно, действует правило: только поток, захвативший [*GIL*](https://python-all.ru/3.1/glossary.html#term-gil), может работать с объектами Python или вызывать функции Python/C API. Чтобы эмулировать параллельное выполнение, интерпретатор регулярно пытается переключать потоки (см. [`sys.setcheckinterval()`](https://python-all.ru/3.1/library/sys.html#sys.setcheckinterval)). Блокировка также снимается вокруг потенциально блокирующих операций ввода-вывода, таких как чтение или запись файла, чтобы в это время могли выполняться другие потоки Python.217218Интерпретатор Python хранит некоторую служебную информацию, специфичную для потока, в структуре данных, называемой [`PyThreadState`](https://python-all.ru/3.1/c-api/init.html#PyThreadState). Также существует одна глобальная переменная, указывающая на текущий [`PyThreadState`](https://python-all.ru/3.1/c-api/init.html#PyThreadState): её можно получить с помощью [`PyThreadState_Get()`](https://python-all.ru/3.1/c-api/init.html#PyThreadState_Get).219220### Освобождение GIL из кода расширения221222Большая часть кода расширения, работающего с [*GIL*](https://python-all.ru/3.1/glossary.html#term-gil), имеет следующую простую структуру:223224```c225Save the thread state in a local variable.226Release the global interpreter lock.227... Do some blocking I/O operation ...228Reacquire the global interpreter lock.229Restore the thread state from the local variable.230```231232Это настолько распространено, что существует пара макросов для упрощения:233234```c235Py_BEGIN_ALLOW_THREADS236... Do some blocking I/O operation ...237Py_END_ALLOW_THREADS238```239240Макрос [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_BEGIN_ALLOW_THREADS) открывает новый блок и объявляет скрытую локальную переменную; макрос [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_END_ALLOW_THREADS) закрывает этот блок. Оба макроса доступны, даже если Python скомпилирован без поддержки потоков (в этом случае они просто разворачиваются в пустую последовательность).241242Когда поддержка потоков включена, указанный выше блок раскрывается в следующий код:243244```c245PyThreadState *_save;246247_save = PyEval_SaveThread();248...Do some blocking I/O operation...249PyEval_RestoreThread(_save);250```251252Вот как работают эти функции: глобальная блокировка интерпретатора используется для защиты указателя на текущее состояние потока. При освобождении блокировки и сохранении состояния потока указатель на текущее состояние потока должен быть получен до освобождения блокировки (поскольку другой поток может немедленно захватить блокировку и сохранить своё состояние потока в глобальной переменной). И наоборот, при захвате блокировки и восстановлении состояния потока блокировка должна быть захвачена до сохранения указателя на состояние потока.253254> **Примечание**255>256> Вызов системных функций ввода-вывода – самый частый случай освобождения GIL, но это также полезно перед длительными вычислениями, не требующими доступа к объектам Python, например при сжатии или криптографических операциях над буферами памяти. Например, стандартные модули [`zlib`](https://python-all.ru/3.1/library/zlib.html#module-zlib) и [`hashlib`](https://python-all.ru/3.1/library/hashlib.html#module-hashlib) освобождают GIL при сжатии или хешировании данных.257258### Потоки, созданные не из Python259260Когда потоки создаются с помощью специальных API Python (например, модуля [`threading`](https://python-all.ru/3.1/library/threading.html#module-threading)), состояние потока автоматически связывается с ними, и приведённый выше код корректен. Однако если потоки создаются из C (например, сторонней библиотекой со своим управлением потоками), они не удерживают GIL, и для них не существует структуры состояния потока.261262Если необходимо вызвать код Python из этих потоков (часто это будет частью API колбэков, предоставляемого упомянутой сторонней библиотекой), сначала нужно зарегистрировать эти потоки в интерпретаторе, создав структуру данных состояния потока, затем захватить GIL и, наконец, сохранить указатель на их состояние потока, прежде чем можно будет начать использовать Python/C API. После завершения следует сбросить указатель состояния потока, освободить GIL и освободить структуру данных состояния потока.263264Функции [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release) выполняют всё вышеописанное автоматически. Типичный идиоматический способ вызова Python из потока C:265266```c267PyGILState_STATE gstate;268gstate = PyGILState_Ensure();269270/* Выполнить действия Python здесь. */271result = CallSomeFunction();272/* вычислить результат или обработать исключение */273274/* Освободить поток. После этой точки API Python не допускается. */275PyGILState_Release(gstate);276```277278Обратите внимание, что функции `PyGILState_*()` предполагают наличие только одного глобального интерпретатора (создаваемого автоматически вызовом [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize)). Python поддерживает создание дополнительных интерпретаторов (с помощью [`Py_NewInterpreter()`](https://python-all.ru/3.1/c-api/init.html#Py_NewInterpreter)), однако смешивание нескольких интерпретаторов с API `PyGILState_*()` не поддерживается.279280Ещё одна важная особенность потоков – их поведение при вызове `fork()` в C. В большинстве систем с `fork()` после разветвления процесса существует только тот поток, который выполнил fork. Это также означает, что блокировки, удерживаемые другими потоками, никогда не будут освобождены. Python решает эту проблему для [`os.fork()`](https://python-all.ru/3.1/library/os.html#os.fork), захватывая используемые им внутренние блокировки перед fork и освобождая их после. Кроме того, он сбрасывает все [*объекты блокировки*](https://python-all.ru/3.1/library/threading.html#lock-objects) в дочернем процессе. При расширении или встраивании Python невозможно сообщить Python о дополнительных (не Python) блокировках, которые необходимо захватить перед fork или сбросить после него. Для достижения того же эффекта пришлось бы использовать средства ОС, такие как `pthread_atfork()`. Кроме того, при расширении или встраивании Python вызов `fork()` напрямую, а не через [`os.fork()`](https://python-all.ru/3.1/library/os.html#os.fork) (и возврат в Python или вызов Python) может привести к взаимоблокировке, если одна из внутренних блокировок Python удерживается потоком, который перестал существовать после fork. [`PyOS_AfterFork()`](https://python-all.ru/3.1/c-api/sys.html#PyOS_AfterFork) пытается сбросить необходимые блокировки, но не всегда может это сделать.281282### API высокого уровня283284Это наиболее часто используемые типы и функции при написании кода C-расширения или при встраивании интерпретатора Python:285286**`PyInterpreterState`**287288Эта структура данных представляет состояние, совместно используемое несколькими взаимодействующими потоками. Потоки, принадлежащие одному интерпретатору, разделяют администрирование модулей и несколько других внутренних элементов. В этой структуре нет открытых членов.289290Потоки, принадлежащие разным интерпретаторам, изначально не разделяют ничего, кроме состояния процесса, такого как доступная память, открытые файловые дескрипторы и т.п. Глобальная блокировка интерпретатора также разделяется всеми потоками, независимо от того, какому интерпретатору они принадлежат.291292**`PyThreadState`**293294Эта структура данных представляет состояние одного потока. Единственная открытая (public) переменная-член –295296[`PyInterpreterState *`](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState)297298`interp`299300, которая указывает на состояние интерпретатора этого потока.301302**void `PyEval_InitThreads`()**303304Инициализирует и захватывает глобальную блокировку интерпретатора. Она должна вызываться в главном потоке перед созданием второго потока или выполнением любых других операций с потоками, таких как [`PyEval_ReleaseLock()`](https://python-all.ru/3.1/c-api/init.html#PyEval_ReleaseLock) или `PyEval_ReleaseThread(tstate)`. Её не нужно вызывать перед [`PyEval_SaveThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SaveThread) или [`PyEval_RestoreThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_RestoreThread).305306При повторном вызове эта функция ничего не делает. Её можно безопасно вызывать до [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize).307308> **Примечание**309>310> Когда существует только главный поток, никакие операции с GIL не нужны. Это обычная ситуация (большинство программ Python не используют потоки), а операции с блокировкой немного замедляют интерпретатор. Поэтому блокировка изначально не создаётся. Такая ситуация эквивалентна захваченной блокировке: если есть только один поток, все обращения к объектам безопасны. Следовательно, когда эта функция инициализирует глобальную блокировку интерпретатора, она также её захватывает. Перед тем как модуль Python [`_thread`](https://python-all.ru/3.1/library/_thread.html#module-_thread) создаёт новый поток, зная, что либо он уже владеет блокировкой, либо блокировка ещё не создана, он вызывает [`PyEval_InitThreads()`](https://python-all.ru/3.1/c-api/init.html#PyEval_InitThreads). Когда этот вызов возвращается, гарантируется, что блокировка создана и вызывающий поток её захватил.311>312> **Не**безопасно вызывать эту функцию, когда неизвестно, какой поток (если таковой есть) в данный момент удерживает глобальную блокировку интерпретатора.313>314> Эта функция недоступна, если поддержка потоков отключена на этапе компиляции.315316**int `PyEval_ThreadsInitialized`()**317318Возвращает ненулевое значение, если319320[`PyEval_InitThreads()`](https://python-all.ru/3.1/c-api/init.html#PyEval_InitThreads)321322была вызвана. Эту функцию можно вызывать без захвата GIL, и поэтому её можно использовать, чтобы избежать вызовов API блокировки при однопоточной работе. Функция недоступна, если поддержка потоков отключена во время компиляции.323324**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `PyEval_SaveThread`()**325326Освобождает глобальную блокировку интерпретатора (если она создана и поддержка потоков включена) и сбрасывает состояние потока в327328*NULL*329330, возвращая предыдущее состояние потока (которое не равно331332*NULL*333334). Если блокировка была создана, текущий поток должен был захватить её. (Эта функция доступна, даже если поддержка потоков отключена на этапе компиляции.)335336**void `PyEval_RestoreThread`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**337338Захватывает глобальную блокировку интерпретатора (если она создана и поддержка потоков включена) и устанавливает состояние потока в339340*tstate*341342, который не должен быть343344*NULL*345346. Если блокировка была создана, текущий поток не должен был захватить её, иначе возникнет взаимоблокировка. (Эта функция доступна, даже если поддержка потоков отключена на этапе компиляции.)347348**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `PyThreadState_Get`()**349350Возвращает текущее состояние потока. Должна быть захвачена глобальная блокировка интерпретатора. Если текущее состояние потока равно351352*NULL*353354, возникает фатальная ошибка (таким образом, вызывающему коду не нужно проверять на355356*NULL*357358).359360**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `PyThreadState_Swap`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**361362Заменяет текущее состояние потока на состояние, заданное аргументом363364*tstate*365366, который может быть367368*NULL*369370. Глобальная блокировка интерпретатора должна быть захвачена и не освобождается.371372**void `PyEval_ReInitThreads`()**373374Эта функция вызывается из375376[`PyOS_AfterFork()`](https://python-all.ru/3.1/c-api/sys.html#PyOS_AfterFork)377378, чтобы гарантировать, что вновь созданные дочерние процессы не удерживают блокировки, относящиеся к потокам, которые не выполняются в дочернем процессе.379380Следующие функции используют локальное хранилище потока и несовместимы с подынтерпретаторами:381382**PyGILState\_STATE `PyGILState_Ensure`()**383384Гарантирует, что текущий поток готов вызывать Python C API независимо от текущего состояния Python или глобальной блокировки интерпретатора. Может вызываться потоком сколько угодно раз, при условии, что каждый вызов соответствует вызову [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release). В общем случае между вызовами [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release) можно использовать другие API, связанные с потоками, при условии, что состояние потока будет восстановлено до предыдущего перед вызовом Release(). Например, допустимо обычное использование макросов [`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_BEGIN_ALLOW_THREADS) и [`Py_END_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_END_ALLOW_THREADS).385386Возвращаемое значение – непрозрачный «дескриптор» состояния потока на момент вызова [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure), и его необходимо передать в [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release), чтобы гарантировать, что Python останется в том же состоянии. Хотя рекурсивные вызовы разрешены, эти дескрипторы *нельзя* разделять – каждый уникальный вызов [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) должен сохранить дескриптор для своего вызова [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release).387388Когда функция возвращает управление, текущий поток будет удерживать GIL и сможет вызывать произвольный код Python. Сбой является фатальной ошибкой.389390**void `PyGILState_Release`(PyGILState\_STATE)**391392Освобождает все ранее захваченные ресурсы. После этого вызова состояние Python будет таким же, как до соответствующего вызова [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) (но обычно это состояние неизвестно вызывающей стороне, поэтому и используется API GILState).393394Каждый вызов [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) должен быть уравновешен вызовом [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release) в том же потоке.395396Следующие макросы обычно используются без точки с запятой в конце; примеры использования можно найти в дистрибутиве исходного кода Python.397398**`Py_BEGIN_ALLOW_THREADS`**399400Этот макрос раскрывается в401402`{ PyThreadState *_save; _save = PyEval_SaveThread();`403404. Обратите внимание, что он содержит открывающую фигурную скобку; он должен быть уравновешен последующим макросом405406[`Py_END_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_END_ALLOW_THREADS)407408. См. выше обсуждение этого макроса. Ничего не делает, если поддержка потоков отключена во время компиляции.409410**`Py_END_ALLOW_THREADS`**411412Этот макрос раскрывается в413414`PyEval_RestoreThread(_save); }`415416. Обратите внимание, что он содержит закрывающую фигурную скобку; он должен быть уравновешен предшествующим макросом417418[`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_BEGIN_ALLOW_THREADS)419420. См. выше обсуждение этого макроса. Ничего не делает, если поддержка потоков отключена во время компиляции.421422**`Py_BLOCK_THREADS`**423424Этот макрос раскрывается в425426`PyEval_RestoreThread(_save);`427428: он эквивалентен429430[`Py_END_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_END_ALLOW_THREADS)431432без закрывающей фигурной скобки. Он не выполняет никаких действий, если поддержка потоков отключена на этапе компиляции.433434**`Py_UNBLOCK_THREADS`**435436Этот макрос раскрывается в437438`_save = PyEval_SaveThread();`439440: он эквивалентен441442[`Py_BEGIN_ALLOW_THREADS`](https://python-all.ru/3.1/c-api/init.html#Py_BEGIN_ALLOW_THREADS)443444без открывающей фигурной скобки и объявления переменной. Он не выполняет никаких действий, если поддержка потоков отключена на этапе компиляции.445446### Низкоуровневый API447448Все следующие функции доступны только при включенной поддержке потоков во время компиляции и должны вызываться только после создания глобальной блокировки интерпретатора.449450**[PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_New`()**451452Создаёт новый объект состояния интерпретатора. Глобальная блокировка интерпретатора может не удерживаться, но может удерживаться, если необходимо сериализовать вызовы этой функции.453454**void `PyInterpreterState_Clear`([PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState) *\*interp*)**455456Сбрасывает всю информацию в объекте состояния интерпретатора. Глобальная блокировка интерпретатора должна удерживаться.457458**void `PyInterpreterState_Delete`([PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState) *\*interp*)**459460Уничтожает объект состояния интерпретатора. Глобальная блокировка интерпретатора может не удерживаться. Состояние интерпретатора должно быть сброшено предварительным вызовом461462[`PyInterpreterState_Clear()`](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState_Clear)463464.465466**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `PyThreadState_New`([PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState) *\*interp*)**467468Создаёт новый объект состояния потока, принадлежащий данному объекту интерпретатора. Глобальная блокировка интерпретатора может не удерживаться, но может удерживаться, если необходимо сериализовать вызовы этой функции.469470**void `PyThreadState_Clear`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**471472Сбрасывает всю информацию в объекте состояния потока. Глобальная блокировка интерпретатора должна удерживаться.473474**void `PyThreadState_Delete`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**475476Уничтожает объект состояния потока. Глобальная блокировка интерпретатора может не удерживаться. Состояние потока должно быть сброшено предварительным вызовом477478[`PyThreadState_Clear()`](https://python-all.ru/3.1/c-api/init.html#PyThreadState_Clear)479480.481482**[PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject)\* `PyThreadState_GetDict`()**483484*Возвращаемое значение: заимствованная ссылка.*485486Возвращает словарь, в котором расширения могут хранить информацию о состоянии, специфичном для потока. Каждое расширение должно использовать уникальный ключ для хранения состояния в словаре. Эту функцию можно вызывать, даже если текущее состояние потока недоступно. Если эта функция возвращает *NULL*, исключение не было возбуждено, и вызывающий код должен считать, что текущее состояние потока недоступно.487488**int `PyThreadState_SetAsyncExc`(long *id*, [PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*exc*)**489490Асинхронно возбуждает исключение в потоке. Аргумент491492*id*493494– это идентификатор потока целевого потока;495496*exc*497498– объект исключения, которое нужно возбудить. Эта функция не похищает никаких ссылок на499500*exc*501502. Чтобы предотвратить наивное злоупотребление, вы должны написать собственное расширение C для её вызова. Должна вызываться с захваченным GIL. Возвращает количество изменённых состояний потока; обычно это единица, но будет нулём, если идентификатор потока не найден. Если503504*exc*505506равно507508`NULL`509510, то ожидающее исключение (если есть) для потока очищается. Эта функция не возбуждает исключений.511512**void `PyEval_AcquireThread`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**513514Захватывает глобальную блокировку интерпретатора и устанавливает текущее состояние потока в *tstate*, который не должен быть *NULL*. Блокировка должна быть создана ранее. Если этот поток уже удерживает блокировку, возникает взаимоблокировка.515516[`PyEval_RestoreThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_RestoreThread) – это функция более высокого уровня, которая всегда доступна (даже если поддержка потоков не включена или потоки не инициализированы).517518**void `PyEval_ReleaseThread`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**519520Сбрасывает текущее состояние потока в *NULL* и освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана ранее и должна удерживаться текущим потоком. Аргумент *tstate*, который не должен быть *NULL*, используется только для проверки того, что он представляет текущее состояние потока – если это не так, сообщается о фатальной ошибке.521522[`PyEval_SaveThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SaveThread) – это функция более высокого уровня, которая всегда доступна (даже если поддержка потоков не включена или потоки не инициализированы).523524**void `PyEval_AcquireLock`()**525526Захватывает глобальную блокировку интерпретатора. Блокировка должна быть создана заранее. Если этот поток уже удерживает блокировку, возникает взаимоблокировка.527528> **Предупреждение**529>530> Эта функция не изменяет текущее состояние потока. Вместо неё используйте [`PyEval_RestoreThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_RestoreThread) или [`PyEval_AcquireThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_AcquireThread) .531532**void `PyEval_ReleaseLock`()**533534Освобождает глобальную блокировку интерпретатора. Блокировка должна быть создана заранее.535536> **Предупреждение**537>538> Эта функция не изменяет текущее состояние потока. Вместо неё используйте [`PyEval_SaveThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SaveThread) или [`PyEval_ReleaseThread()`](https://python-all.ru/3.1/c-api/init.html#PyEval_ReleaseThread) .539540## Поддержка под-интерпретаторов541542Хотя в большинстве случаев вы будете встраивать только один интерпретатор Python, бывают ситуации, когда необходимо создать несколько независимых интерпретаторов в одном процессе и, возможно, даже в одном потоке. Суб-интерпретаторы позволяют это сделать. Переключаться между суб-интерпретаторами можно с помощью функции [`PyThreadState_Swap()`](https://python-all.ru/3.1/c-api/init.html#PyThreadState_Swap). Создавать и уничтожать их можно с помощью следующих функций:543544**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `Py_NewInterpreter`()**545546Создаёт новый суб-интерпретатор. Это (почти) полностью изолированное окружение для выполнения кода Python. В частности, новый интерпретатор имеет отдельные, независимые версии всех импортированных модулей, включая фундаментальные модули [`builtins`](https://python-all.ru/3.1/library/builtins.html#module-builtins), [`__main__`](https://python-all.ru/3.1/library/__main__.html#module-__main__) и [`sys`](https://python-all.ru/3.1/library/sys.html#module-sys). Таблица загруженных модулей (`sys.modules`) и путь поиска модулей (`sys.path`) также являются отдельными. Новое окружение не имеет переменной `sys.argv`. Оно имеет новые объекты файловых потоков стандартного ввода/вывода `sys.stdin`, `sys.stdout` и `sys.stderr` (однако они ссылаются на те же базовые файловые дескрипторы).547548Возвращаемое значение указывает на первое состояние потока, созданное в новом под-интерпретаторе. Это состояние потока создаётся в текущем состоянии потока. Обратите внимание, что фактический поток не создаётся; см. обсуждение состояний потока ниже. Если создание нового интерпретатора не удалось, возвращается *NULL*; исключение не устанавливается, поскольку состояние исключения хранится в текущем состоянии потока, и текущего состояния потока может не быть. (Как и все другие функции Python/C API, глобальная блокировка интерпретатора должна быть захвачена перед вызовом этой функции и остаётся захваченной при возврате; однако, в отличие от большинства других функций Python/C API, при входе необязательно наличие текущего состояния потока.)549550Модули расширения разделяются между (суб-)интерпретаторами следующим образом: при первом импорте конкретного расширения оно инициализируется обычным образом, и (поверхностная) копия словаря его модуля сохраняется. Когда то же расширение импортируется другим (суб-)интерпретатором, инициализируется новый модуль и заполняется содержимым этой копии; функция `init` расширения не вызывается. Обратите внимание, что это отличается от того, что происходит, когда расширение импортируется после полной переинициализации интерпретатора вызовами [`Py_Finalize()`](https://python-all.ru/3.1/c-api/init.html#Py_Finalize) и [`Py_Initialize()`](https://python-all.ru/3.1/c-api/init.html#Py_Initialize); в этом случае функция `initmodule` расширения *вызывается* снова.551552**void `Py_EndInterpreter`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**553554Уничтожает (суб-)интерпретатор, представленный данным состоянием потока. Указанное состояние потока должно быть текущим состоянием потока. См. обсуждение состояний потоков ниже. После возврата из вызова текущее состояние потока равно *NULL*. Все состояния потоков, связанные с этим интерпретатором, уничтожаются. (Глобальная блокировка интерпретатора должна быть захвачена перед вызовом этой функции и остаётся захваченной при возврате.) [`Py_Finalize()`](https://python-all.ru/3.1/c-api/init.html#Py_Finalize) уничтожит все суб-интерпретаторы, которые не были явно уничтожены к этому моменту.555556### Ошибки и предостережения557558Поскольку суб-интерпретаторы (и главный интерпретатор) являются частью одного процесса, изоляция между ними не идеальна – например, с помощью низкоуровневых файловых операций, таких как [`os.close()`](https://python-all.ru/3.1/library/os.html#os.close), они могут (случайно или злонамеренно) влиять на открытые файлы друг друга. Из-за способа разделения расширений между (суб-)интерпретаторами некоторые расширения могут работать неправильно; это особенно вероятно, когда расширение использует (статические) глобальные переменные или когда расширение манипулирует словарём своего модуля после инициализации. Можно вставлять объекты, созданные в одном суб-интерпретаторе, в пространство имён другого суб-интерпретатора; это следует делать с большой осторожностью, чтобы избежать совместного использования пользовательских функций, методов, экземпляров или классов между суб-интерпретаторами, поскольку операции импорта, выполняемые такими объектами, могут повлиять на словарь загруженных модулей неправильного (суб-)интерпретатора.559560Также обратите внимание, что совместное использование этой функциональности с API `PyGILState_*()` является деликатным, поскольку эти API предполагают биекцию между состояниями потоков Python и потоками уровня ОС, а это предположение нарушается наличием суб-интерпретаторов. Настоятельно рекомендуется не переключать суб-интерпретаторы между парой соответствующих вызовов [`PyGILState_Ensure()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Ensure) и [`PyGILState_Release()`](https://python-all.ru/3.1/c-api/init.html#PyGILState_Release). Кроме того, расширения (такие как [`ctypes`](https://python-all.ru/3.1/library/ctypes.html#module-ctypes)), использующие эти API для вызова кода Python из потоков, созданных не в Python, вероятно, будут работать некорректно при использовании суб-интерпретаторов.561562## Асинхронные уведомления563564Предусмотрен механизм асинхронных уведомлений для главного потока интерпретатора. Эти уведомления представляют собой указатель на функцию и аргумент типа void.565566При каждой проверке, когда глобальная блокировка интерпретатора освобождается и захватывается снова, Python также вызывает все зарегистрированные функции. Это может использоваться, например, асинхронными обработчиками ввода-вывода. Уведомление может быть запланировано из рабочего потока, а фактический вызов будет выполнен главным потоком при первой возможности, когда он удерживает глобальную блокировку интерпретатора и может вызывать любые функции Python API.567568**int `Py_AddPendingCall`(int (\*func)(void *\*)*, void *\*arg*)**569570Отправляет уведомление главному потоку Python. В случае успеха *func* будет вызвана с аргументом *arg* при первой возможности. Функция *func* будет вызвана с удержанием глобальной блокировки интерпретатора, что позволит ей использовать полный Python API и выполнять любые действия, например, устанавливать атрибуты объекта для сигнализации о завершении ввода-вывода. Она должна вернуть 0 в случае успеха или -1, сообщая об исключении. Функция уведомления не будет прервана для рекурсивного выполнения другого асинхронного уведомления, но она всё же может быть прервана для переключения потоков, если глобальная блокировка интерпретатора освобождена, например, если она вызывает код Python.571572Эта функция возвращает 0 в случае успеха, что означает, что уведомление было запланировано. В противном случае, например, если буфер уведомлений заполнен, она возвращает -1, не устанавливая никакого исключения.573574Эта функция может быть вызвана из любого потока, будь то поток Python или другой системный поток. Если это поток Python, неважно, удерживает ли он глобальную блокировку интерпретатора.575576Новое в версии 3.1.577578## Профилирование и трассировка579580Интерпретатор Python предоставляет низкоуровневую поддержку для подключения средств профилирования и трассировки выполнения. Они используются в инструментах профилирования, отладки и анализа покрытия.581582Этот C-интерфейс позволяет коду профилирования или трассировки избежать накладных расходов на вызов через вызываемые объекты уровня Python, выполняя вместо этого прямой вызов C-функции. Основные характеристики механизма не изменились; интерфейс позволяет устанавливать функции трассировки для каждого потока, а базовые события, сообщаемые функции трассировки, такие же, как и в предыдущих версиях для функций трассировки уровня Python.583584**int `(*Py_tracefunc)`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*obj*, PyFrameObject *\*frame*, int *what*, [PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*arg*)**585586Тип функции трассировки, зарегистрированной с помощью [`PyEval_SetProfile()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SetProfile) и [`PyEval_SetTrace()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SetTrace). Первый параметр – это объект, переданный функции регистрации как *obj*, *frame* – объект кадра, к которому относится событие, *what* – одна из констант [`PyTrace_CALL`](https://python-all.ru/3.1/c-api/init.html#PyTrace_CALL), [`PyTrace_EXCEPTION`](https://python-all.ru/3.1/c-api/init.html#PyTrace_EXCEPTION), [`PyTrace_LINE`](https://python-all.ru/3.1/c-api/init.html#PyTrace_LINE), [`PyTrace_RETURN`](https://python-all.ru/3.1/c-api/init.html#PyTrace_RETURN), [`PyTrace_C_CALL`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_CALL), [`PyTrace_C_EXCEPTION`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_EXCEPTION), или [`PyTrace_C_RETURN`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_RETURN), а *arg* зависит от значения *what*:587588| Значение *what* | Смысл *arg* |589| --- | --- |590| [`PyTrace_CALL`](https://python-all.ru/3.1/c-api/init.html#PyTrace_CALL) | Всегда *NULL*. |591| [`PyTrace_EXCEPTION`](https://python-all.ru/3.1/c-api/init.html#PyTrace_EXCEPTION) | Информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/3.1/library/sys.html#sys.exc_info). |592| [`PyTrace_LINE`](https://python-all.ru/3.1/c-api/init.html#PyTrace_LINE) | Всегда *NULL*. |593| [`PyTrace_RETURN`](https://python-all.ru/3.1/c-api/init.html#PyTrace_RETURN) | Значение, возвращаемое вызывающему коду, или *NULL*, если вызвано исключением. |594| [`PyTrace_C_CALL`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_CALL) | Вызываемый объект функции. |595| [`PyTrace_C_EXCEPTION`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_EXCEPTION) | Вызываемый объект функции. |596| [`PyTrace_C_RETURN`](https://python-all.ru/3.1/c-api/init.html#PyTrace_C_RETURN) | Вызываемый объект функции. |597598**int `PyTrace_CALL`**599600Значение параметра601602*what*603604функции605606[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)607608, когда сообщается о новом вызове функции или метода, или о новом входе в генератор. Обратите внимание, что создание итератора для функции-генератора не сообщается, поскольку нет передачи управления байт-коду Python в соответствующем фрейме.609610**int `PyTrace_EXCEPTION`**611612Значение параметра613614*what*615616функции617618[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)619620, когда возникло исключение. Функция обратного вызова вызывается с этим значением для621622*what*623624после обработки любого байт-кода, после которого исключение устанавливается в выполняемом фрейме. В результате, когда распространение исключения вызывает разворачивание стека Python, обратный вызов вызывается при возврате в каждый фрейм по мере распространения исключения. Только функции трассировки получают эти события; профилировщику они не нужны.625626**int `PyTrace_LINE`**627628Значение, передаваемое в качестве параметра629630*what*631632в трассировочную функцию (но не в профилирующую функцию), когда сообщается о событии номера строки.633634**int `PyTrace_RETURN`**635636Значение параметра637638*what*639640функций641642[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)643644, когда вызов возвращается без распространения исключения.645646**int `PyTrace_C_CALL`**647648Значение параметра649650*what*651652функций653654[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)655656, когда функция на C собирается быть вызванной.657658**int `PyTrace_C_EXCEPTION`**659660Значение параметра661662*what*663664функций665666[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)667668, когда функция на C возбудила исключение.669670**int `PyTrace_C_RETURN`**671672Значение параметра673674*what*675676функций677678[`Py_tracefunc`](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc)679680, когда функция на C вернулась.681682**void `PyEval_SetProfile`([Py\_tracefunc](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc) *func*, [PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*obj*)**683684Устанавливает функцию профилировщика в685686*func*687688. Параметр689690*obj*691692передаётся функции в качестве первого аргумента и может быть любым объектом Python или693694*NULL*695696. Если функции профилировщика требуется поддерживать состояние, использование разных значений697698*obj*699700для каждого потока предоставляет удобное и потокобезопасное место для его хранения. Функция профилировщика вызывается для всех отслеживаемых событий, кроме событий с номерами строк.701702**void `PyEval_SetTrace`([Py\_tracefunc](https://python-all.ru/3.1/c-api/init.html#Py_tracefunc) *func*, [PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*obj*)**703704Устанавливает функцию трассировки в705706*func*707708. Это похоже на709710[`PyEval_SetProfile()`](https://python-all.ru/3.1/c-api/init.html#PyEval_SetProfile)711712, за исключением того, что функция трассировки получает события номеров строк.713714**[PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject)\* `PyEval_GetCallStats`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*self*)**715716Возвращает кортеж счётчиков вызовов функций. Для позиций в кортеже определены константы:717718| Имя | Значение |719| --- | --- |720| `PCALL_ALL` | 0 |721| `PCALL_FUNCTION` | 1 |722| `PCALL_FAST_FUNCTION` | 2 |723| `PCALL_FASTER_FUNCTION` | 3 |724| `PCALL_METHOD` | 4 |725| `PCALL_BOUND_METHOD` | 5 |726| `PCALL_CFUNCTION` | 6 |727| `PCALL_TYPE` | 7 |728| `PCALL_GENERATOR` | 8 |729| `PCALL_OTHER` | 9 |730| `PCALL_POP` | 10 |731732`PCALL_FAST_FUNCTION` означает, что создавать кортеж аргументов не требуется. `PCALL_FASTER_FUNCTION` означает, что используется код быстрой настройки фрейма.733734Если есть вызов метода, который можно оптимизировать, изменив кортеж аргументов и вызвав функцию напрямую, он записывается дважды.735736Эта функция доступна только при компиляции Python с определённым `CALL_PROFILE`.737738## Поддержка расширенного отладчика739740Эти функции предназначены только для использования расширенными инструментами отладки.741742**[PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_Head`()**743744Возвращает объект состояния интерпретатора, находящийся в начале списка всех таких объектов.745746**[PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState)\* `PyInterpreterState_Next`([PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState) *\*interp*)**747748Возвращает следующий объект состояния интерпретатора после749750*interp*751752из списка всех таких объектов.753754**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) \* `PyInterpreterState_ThreadHead`([PyInterpreterState](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState) *\*interp*)**755756Возвращает указатель на первый объект757758[`PyThreadState`](https://python-all.ru/3.1/c-api/init.html#PyThreadState)759760в списке\\nпотоков, связанных с интерпретатором761762*interp*763764.765766**[PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState)\* `PyThreadState_Next`([PyThreadState](https://python-all.ru/3.1/c-api/init.html#PyThreadState) *\*tstate*)**767768Возвращает следующий объект состояния потока после769770*tstate*771772из списка всех таких объектов, принадлежащих одному и тому же объекту773774[`PyInterpreterState`](https://python-all.ru/3.1/c-api/init.html#PyInterpreterState)775776.777