Files
hustoj/web/python-docs/c-api/init.html
2025-03-09 17:10:56 +08:00

1490 lines
168 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>初始化,最终化和线程 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="Python初始化配置" href="init_config.html" />
<link rel="prev" title="DateTime 对象" href="datetime.html" />
<link rel="canonical" href="https://docs.python.org/3/c-api/init.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">初始化,最终化和线程</a><ul>
<li><a class="reference internal" href="#before-python-initialization">在Python初始化之前</a></li>
<li><a class="reference internal" href="#global-configuration-variables">全局配置变量</a></li>
<li><a class="reference internal" href="#initializing-and-finalizing-the-interpreter">初始化和最终化解释器</a></li>
<li><a class="reference internal" href="#process-wide-parameters">进程级参数</a></li>
<li><a class="reference internal" href="#thread-state-and-the-global-interpreter-lock">线程状态和全局解释器锁</a><ul>
<li><a class="reference internal" href="#releasing-the-gil-from-extension-code">从扩展扩展代码中释放 GIL</a></li>
<li><a class="reference internal" href="#non-python-created-threads">非Python创建的线程</a></li>
<li><a class="reference internal" href="#cautions-about-fork">有关 fork() 的注意事项</a></li>
<li><a class="reference internal" href="#high-level-api">高阶 API</a></li>
<li><a class="reference internal" href="#low-level-api">底层级 API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#sub-interpreter-support">子解释器支持</a><ul>
<li><a class="reference internal" href="#bugs-and-caveats">错误和警告</a></li>
</ul>
</li>
<li><a class="reference internal" href="#asynchronous-notifications">异步通知</a></li>
<li><a class="reference internal" href="#profiling-and-tracing">分析和跟踪</a></li>
<li><a class="reference internal" href="#advanced-debugger-support">高级调试器支持</a></li>
<li><a class="reference internal" href="#thread-local-storage-support">线程本地存储支持</a><ul>
<li><a class="reference internal" href="#thread-specific-storage-tss-api">线程专属存储 (TSS) API</a><ul>
<li><a class="reference internal" href="#dynamic-allocation">动态分配</a></li>
<li><a class="reference internal" href="#methods">方法</a></li>
</ul>
</li>
<li><a class="reference internal" href="#thread-local-storage-tls-api">线程本地存储 (TLS) API</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="datetime.html"
title="上一章">DateTime 对象</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="init_config.html"
title="下一章">Python初始化配置</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/c-api/init.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/c-api/init.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="init_config.html" title="Python初始化配置"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="datetime.html" title="DateTime 对象"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python/C API 参考手册</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="initialization-finalization-and-threads">
<span id="initialization"></span><h1>初始化,最终化和线程<a class="headerlink" href="#initialization-finalization-and-threads" title="永久链接至标题"></a></h1>
<p>请参阅 <a class="reference internal" href="init_config.html#init-config"><span class="std std-ref">Python 初始化配置</span></a></p>
<section id="before-python-initialization">
<span id="pre-init-safe"></span><h2>在Python初始化之前<a class="headerlink" href="#before-python-initialization" title="永久链接至标题"></a></h2>
<p>在一个植入了 Python 的应用程序中,<a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 函数必须在任何其他 Python/C API 函数之前被调用;例外的只有个别函数和 <a class="reference internal" href="#global-conf-vars"><span class="std std-ref">全局配置变量</span></a></p>
<p>在初始化Python之前可以安全地调用以下函数</p>
<ul class="simple">
<li><p>配置函数:</p>
<ul>
<li><p><a class="reference internal" href="import.html#c.PyImport_AppendInittab" title="PyImport_AppendInittab"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyImport_AppendInittab()</span></code></a></p></li>
<li><p><a class="reference internal" href="import.html#c.PyImport_ExtendInittab" title="PyImport_ExtendInittab"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyImport_ExtendInittab()</span></code></a></p></li>
<li><p><code class="xref c c-func docutils literal notranslate"><span class="pre">PyInitFrozenExtensions()</span></code></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_SetAllocator" title="PyMem_SetAllocator"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_SetAllocator()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_SetupDebugHooks" title="PyMem_SetupDebugHooks"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_SetupDebugHooks()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyObject_SetArenaAllocator" title="PyObject_SetArenaAllocator"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_SetArenaAllocator()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_SetPath" title="Py_SetPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetPath()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_SetPythonHome" title="Py_SetPythonHome"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetPythonHome()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_SetStandardStreamEncoding" title="Py_SetStandardStreamEncoding"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetStandardStreamEncoding()</span></code></a></p></li>
<li><p><a class="reference internal" href="sys.html#c.PySys_AddWarnOption" title="PySys_AddWarnOption"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_AddWarnOption()</span></code></a></p></li>
<li><p><a class="reference internal" href="sys.html#c.PySys_AddXOption" title="PySys_AddXOption"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_AddXOption()</span></code></a></p></li>
<li><p><a class="reference internal" href="sys.html#c.PySys_ResetWarnOptions" title="PySys_ResetWarnOptions"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_ResetWarnOptions()</span></code></a></p></li>
</ul>
</li>
<li><p>信息函数:</p>
<ul>
<li><p><a class="reference internal" href="#c.Py_IsInitialized" title="Py_IsInitialized"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_IsInitialized()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_GetAllocator" title="PyMem_GetAllocator"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_GetAllocator()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyObject_GetArenaAllocator" title="PyObject_GetArenaAllocator"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetArenaAllocator()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_GetBuildInfo" title="Py_GetBuildInfo"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetBuildInfo()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_GetCompiler" title="Py_GetCompiler"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetCompiler()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_GetCopyright" title="Py_GetCopyright"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetCopyright()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_GetPlatform" title="Py_GetPlatform"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPlatform()</span></code></a></p></li>
<li><p><a class="reference internal" href="#c.Py_GetVersion" title="Py_GetVersion"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetVersion()</span></code></a></p></li>
</ul>
</li>
<li><p>工具</p>
<ul>
<li><p><a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a></p></li>
</ul>
</li>
<li><p>内存分配器:</p>
<ul>
<li><p><a class="reference internal" href="memory.html#c.PyMem_RawMalloc" title="PyMem_RawMalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawMalloc()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_RawCalloc" title="PyMem_RawCalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawCalloc()</span></code></a></p></li>
<li><p><a class="reference internal" href="memory.html#c.PyMem_RawFree" title="PyMem_RawFree"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawFree()</span></code></a></p></li>
</ul>
</li>
</ul>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>以下函数 <strong>不应该</strong><a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>: <a class="reference internal" href="sys.html#c.Py_EncodeLocale" title="Py_EncodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_EncodeLocale()</span></code></a>, <a class="reference internal" href="#c.Py_GetPath" title="Py_GetPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPath()</span></code></a>, <a class="reference internal" href="#c.Py_GetPrefix" title="Py_GetPrefix"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPrefix()</span></code></a>, <a class="reference internal" href="#c.Py_GetExecPrefix" title="Py_GetExecPrefix"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetExecPrefix()</span></code></a>, <a class="reference internal" href="#c.Py_GetProgramFullPath" title="Py_GetProgramFullPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetProgramFullPath()</span></code></a>, <a class="reference internal" href="#c.Py_GetPythonHome" title="Py_GetPythonHome"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPythonHome()</span></code></a>, <a class="reference internal" href="#c.Py_GetProgramName" title="Py_GetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetProgramName()</span></code></a><a class="reference internal" href="#c.PyEval_InitThreads" title="PyEval_InitThreads"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_InitThreads()</span></code></a> 前调用。</p>
</div>
</section>
<section id="global-configuration-variables">
<span id="global-conf-vars"></span><h2>全局配置变量<a class="headerlink" href="#global-configuration-variables" title="永久链接至标题"></a></h2>
<p>Python 有负责控制全局配置中不同特性和选项的变量。这些标志默认被 <a class="reference internal" href="../using/cmdline.html#using-on-interface-options"><span class="std std-ref">命令行选项</span></a></p>
<p>当一个选项设置一个旗标时,该旗标的值将是设置选项的次数。 例如,<code class="docutils literal notranslate"><span class="pre">-b</span></code> 会将 <a class="reference internal" href="#c.Py_BytesWarningFlag" title="Py_BytesWarningFlag"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_BytesWarningFlag</span></code></a> 设为 1 而 <code class="docutils literal notranslate"><span class="pre">-bb</span></code> 会将 <a class="reference internal" href="#c.Py_BytesWarningFlag" title="Py_BytesWarningFlag"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_BytesWarningFlag</span></code></a> 设为 2.</p>
<dl class="var">
<dt id="c.Py_BytesWarningFlag">
int <code class="sig-name descname">Py_BytesWarningFlag</code><a class="headerlink" href="#c.Py_BytesWarningFlag" title="永久链接至目标"></a></dt>
<dd><p>当将 <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a><a class="reference internal" href="../library/stdtypes.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytearray</span></code></a><a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> 比较或者将 <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a><a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a> 比较时发出警告。 如果大于等于 <code class="docutils literal notranslate"><span class="pre">2</span></code> 则报错。</p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-b"><code class="xref std std-option docutils literal notranslate"><span class="pre">-b</span></code></a> 选项设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_DebugFlag">
int <code class="sig-name descname">Py_DebugFlag</code><a class="headerlink" href="#c.Py_DebugFlag" title="永久链接至目标"></a></dt>
<dd><p>开启解析器调试输出(限专家使用,依赖于编译选项)。</p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-d"><code class="xref std std-option docutils literal notranslate"><span class="pre">-d</span></code></a> 选项和 <span class="target" id="index-66"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONDEBUG"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONDEBUG</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_DontWriteBytecodeFlag">
int <code class="sig-name descname">Py_DontWriteBytecodeFlag</code><a class="headerlink" href="#c.Py_DontWriteBytecodeFlag" title="永久链接至目标"></a></dt>
<dd><p>如果设置为非零, Python 不会在导入源代码时尝试写入 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件</p>
<p><a class="reference internal" href="../using/cmdline.html#id1"><code class="xref std std-option docutils literal notranslate"><span class="pre">-B</span></code></a> 选项和 <span class="target" id="index-67"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONDONTWRITEBYTECODE</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_FrozenFlag">
int <code class="sig-name descname">Py_FrozenFlag</code><a class="headerlink" href="#c.Py_FrozenFlag" title="永久链接至目标"></a></dt>
<dd><p>当在 <a class="reference internal" href="#c.Py_GetPath" title="Py_GetPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPath()</span></code></a> 中计算模块搜索路径时屏蔽错误消息。</p>
<p><code class="docutils literal notranslate"><span class="pre">_freeze_importlib</span></code><code class="docutils literal notranslate"><span class="pre">frozenmain</span></code> 程序使用的私有旗标。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_HashRandomizationFlag">
int <code class="sig-name descname">Py_HashRandomizationFlag</code><a class="headerlink" href="#c.Py_HashRandomizationFlag" title="永久链接至目标"></a></dt>
<dd><p>如果 <span class="target" id="index-68"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONHASHSEED"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONHASHSEED</span></code></a> 环境变量被设为非空字符串则设为 <code class="docutils literal notranslate"><span class="pre">1</span></code></p>
<p>如果该旗标为非零值,则读取 <span class="target" id="index-69"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONHASHSEED"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONHASHSEED</span></code></a> 环境变量来初始化加密哈希种子。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_IgnoreEnvironmentFlag">
int <code class="sig-name descname">Py_IgnoreEnvironmentFlag</code><a class="headerlink" href="#c.Py_IgnoreEnvironmentFlag" title="永久链接至目标"></a></dt>
<dd><p>忽略所有 <span class="target" id="index-70"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHON*</span></code> 环境变量,例如,已设置的 <span class="target" id="index-71"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONPATH"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONPATH</span></code></a><span class="target" id="index-72"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONHOME"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONHOME</span></code></a></p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-e"><code class="xref std std-option docutils literal notranslate"><span class="pre">-E</span></code></a><a class="reference internal" href="../using/cmdline.html#id2"><code class="xref std std-option docutils literal notranslate"><span class="pre">-I</span></code></a> 选项设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_InspectFlag">
int <code class="sig-name descname">Py_InspectFlag</code><a class="headerlink" href="#c.Py_InspectFlag" title="永久链接至目标"></a></dt>
<dd><p>当将脚本作为第一个参数传入或是使用了 <a class="reference internal" href="../using/cmdline.html#cmdoption-c"><code class="xref std std-option docutils literal notranslate"><span class="pre">-c</span></code></a> 选项时,则会在执行该脚本或命令后进入交互模式,即使在 <a class="reference internal" href="../library/sys.html#sys.stdin" title="sys.stdin"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdin</span></code></a> 并非一个终端时也是如此。</p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-i"><code class="xref std std-option docutils literal notranslate"><span class="pre">-i</span></code></a> 选项和 <span class="target" id="index-73"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONINSPECT"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONINSPECT</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_InteractiveFlag">
int <code class="sig-name descname">Py_InteractiveFlag</code><a class="headerlink" href="#c.Py_InteractiveFlag" title="永久链接至目标"></a></dt>
<dd><p><a class="reference internal" href="../using/cmdline.html#cmdoption-i"><code class="xref std std-option docutils literal notranslate"><span class="pre">-i</span></code></a> 选项设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_IsolatedFlag">
int <code class="sig-name descname">Py_IsolatedFlag</code><a class="headerlink" href="#c.Py_IsolatedFlag" title="永久链接至目标"></a></dt>
<dd><p>以隔离模式运行 Python. 在隔离模式下 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 将不包含脚本的目录或用户的 site-packages 目录。</p>
<p><a class="reference internal" href="../using/cmdline.html#id2"><code class="xref std std-option docutils literal notranslate"><span class="pre">-I</span></code></a> 选项设置。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
</dd></dl>
<dl class="var">
<dt id="c.Py_LegacyWindowsFSEncodingFlag">
int <code class="sig-name descname">Py_LegacyWindowsFSEncodingFlag</code><a class="headerlink" href="#c.Py_LegacyWindowsFSEncodingFlag" title="永久链接至目标"></a></dt>
<dd><p>If the flag is non-zero, use the <code class="docutils literal notranslate"><span class="pre">mbcs</span></code> encoding instead of the UTF-8
encoding for the filesystem encoding.</p>
<p>如果 <span class="target" id="index-74"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONLEGACYWINDOWSFSENCODING"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONLEGACYWINDOWSFSENCODING</span></code></a> 环境变量被设为非空字符串则设为 <code class="docutils literal notranslate"><span class="pre">1</span></code></p>
<p>更多详情请参阅 <span class="target" id="index-75"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0529"><strong>PEP 529</strong></a></p>
<p class="availability"><a class="reference internal" href="../library/intro.html#availability"><span class="std std-ref">可用性</span></a>: Windows。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_LegacyWindowsStdioFlag">
int <code class="sig-name descname">Py_LegacyWindowsStdioFlag</code><a class="headerlink" href="#c.Py_LegacyWindowsStdioFlag" title="永久链接至目标"></a></dt>
<dd><p>如果该旗标为非零值,则会使用 <a class="reference internal" href="../library/io.html#io.FileIO" title="io.FileIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.FileIO</span></code></a> 而不是 <code class="xref py py-class docutils literal notranslate"><span class="pre">WindowsConsoleIO</span></code> 作为 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a> 的标准流。</p>
<p>如果 <span class="target" id="index-76"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONLEGACYWINDOWSSTDIO"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONLEGACYWINDOWSSTDIO</span></code></a> 环境变量被设为非空字符串则设为 <code class="docutils literal notranslate"><span class="pre">1</span></code></p>
<p>有关更多详细信息,请参阅 <span class="target" id="index-77"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0528"><strong>PEP 528</strong></a></p>
<p class="availability"><a class="reference internal" href="../library/intro.html#availability"><span class="std std-ref">可用性</span></a>: Windows。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_NoSiteFlag">
int <code class="sig-name descname">Py_NoSiteFlag</code><a class="headerlink" href="#c.Py_NoSiteFlag" title="永久链接至目标"></a></dt>
<dd><p>禁用 <a class="reference internal" href="../library/site.html#module-site" title="site: Module responsible for site-specific configuration."><code class="xref py py-mod docutils literal notranslate"><span class="pre">site</span></code></a> 的导入及其所附带的基于站点对 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 的操作。 如果 <a class="reference internal" href="../library/site.html#module-site" title="site: Module responsible for site-specific configuration."><code class="xref py py-mod docutils literal notranslate"><span class="pre">site</span></code></a> 会在稍后被显式地导入也会禁用这些操作 (如果你希望触发它们则应调用 <a class="reference internal" href="../library/site.html#site.main" title="site.main"><code class="xref py py-func docutils literal notranslate"><span class="pre">site.main()</span></code></a>)。</p>
<p><a class="reference internal" href="../using/cmdline.html#id3"><code class="xref std std-option docutils literal notranslate"><span class="pre">-S</span></code></a> 选项设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_NoUserSiteDirectory">
int <code class="sig-name descname">Py_NoUserSiteDirectory</code><a class="headerlink" href="#c.Py_NoUserSiteDirectory" title="永久链接至目标"></a></dt>
<dd><p>不要将 <a class="reference internal" href="../library/site.html#site.USER_SITE" title="site.USER_SITE"><code class="xref py py-data docutils literal notranslate"><span class="pre">用户</span> <span class="pre">site-packages</span> <span class="pre">目录</span></code></a> 添加到 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a></p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-s"><code class="xref std std-option docutils literal notranslate"><span class="pre">-s</span></code></a><a class="reference internal" href="../using/cmdline.html#id2"><code class="xref std std-option docutils literal notranslate"><span class="pre">-I</span></code></a> 选项以及 <span class="target" id="index-78"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONNOUSERSITE"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONNOUSERSITE</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_OptimizeFlag">
int <code class="sig-name descname">Py_OptimizeFlag</code><a class="headerlink" href="#c.Py_OptimizeFlag" title="永久链接至目标"></a></dt>
<dd><p><a class="reference internal" href="../using/cmdline.html#cmdoption-o"><code class="xref std std-option docutils literal notranslate"><span class="pre">-O</span></code></a> 选项和 <span class="target" id="index-79"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONOPTIMIZE"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONOPTIMIZE</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_QuietFlag">
int <code class="sig-name descname">Py_QuietFlag</code><a class="headerlink" href="#c.Py_QuietFlag" title="永久链接至目标"></a></dt>
<dd><p>即使在交互模式下也不显示版权和版本信息。</p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-q"><code class="xref std std-option docutils literal notranslate"><span class="pre">-q</span></code></a> 选项设置。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能.</span></p>
</div>
</dd></dl>
<dl class="var">
<dt id="c.Py_UnbufferedStdioFlag">
int <code class="sig-name descname">Py_UnbufferedStdioFlag</code><a class="headerlink" href="#c.Py_UnbufferedStdioFlag" title="永久链接至目标"></a></dt>
<dd><p>强制 stdout 和 stderr 流不带缓冲。</p>
<p><a class="reference internal" href="../using/cmdline.html#cmdoption-u"><code class="xref std std-option docutils literal notranslate"><span class="pre">-u</span></code></a> 选项和 <span class="target" id="index-80"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONUNBUFFERED"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONUNBUFFERED</span></code></a> 环境变量设置。</p>
</dd></dl>
<dl class="var">
<dt id="c.Py_VerboseFlag">
int <code class="sig-name descname">Py_VerboseFlag</code><a class="headerlink" href="#c.Py_VerboseFlag" title="永久链接至目标"></a></dt>
<dd><p>每次初始化模块时打印一条消息,显示加载模块的位置(文件名或内置模块)。 如果大于或等于 <code class="docutils literal notranslate"><span class="pre">2</span></code>,则为搜索模块时检查的每个文件打印一条消息。 此外还会在退出时提供模块清理信息。</p>
<p><a class="reference internal" href="../using/cmdline.html#id4"><code class="xref std std-option docutils literal notranslate"><span class="pre">-v</span></code></a> 选项和 <span class="target" id="index-81"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONVERBOSE"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONVERBOSE</span></code></a> 环境变量设置。</p>
</dd></dl>
</section>
<section id="initializing-and-finalizing-the-interpreter">
<h2>初始化和最终化解释器<a class="headerlink" href="#initializing-and-finalizing-the-interpreter" title="永久链接至标题"></a></h2>
<dl class="function">
<dt id="c.Py_Initialize">
void <code class="sig-name descname">Py_Initialize</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_Initialize" title="永久链接至目标"></a></dt>
<dd><p id="index-16">初始化 Python 解释器。 在嵌入 Python 的应用程序中,它应当在使用任何其他 Python/C API 函数之前被调用;请参阅 <a class="reference internal" href="#pre-init-safe"><span class="std std-ref">在 Python 初始化之前</span></a> 了解少数的例外情况。</p>
<p>这将初始化已加载模块表 (<code class="docutils literal notranslate"><span class="pre">sys.modules</span></code>),并创建基本模块 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a><a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a><a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a>。 它还会初始化模块搜索路径 (<code class="docutils literal notranslate"><span class="pre">sys.path</span></code>)。 它不会设置 <code class="docutils literal notranslate"><span class="pre">sys.argv</span></code>;如有需要请使用 <a class="reference internal" href="#c.PySys_SetArgvEx" title="PySys_SetArgvEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_SetArgvEx()</span></code></a>。 当第二次调用时 (在未事先调用 <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> 的情况下) 将不会执行任何操作。 它没有返回值;如果初始化失败则会发生致命错误。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>在 Windows 上,将控制台模式从 <code class="docutils literal notranslate"><span class="pre">O_TEXT</span></code> 改为 <code class="docutils literal notranslate"><span class="pre">O_BINARY</span></code>,这还将影响使用 C 运行时的非 Python 的控制台使用。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.Py_InitializeEx">
void <code class="sig-name descname">Py_InitializeEx</code><span class="sig-paren">(</span>int<em> initsigs</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_InitializeEx" title="永久链接至目标"></a></dt>
<dd><p>如果 <em>initsigs</em><code class="docutils literal notranslate"><span class="pre">1</span></code> 则该函数的工作方式与 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 类似。 如果 <em>initsigs</em><code class="docutils literal notranslate"><span class="pre">0</span></code>,它将跳过信号处理器的初始化注册,这在嵌入 Python 时可能会很有用处。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_IsInitialized">
int <code class="sig-name descname">Py_IsInitialized</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_IsInitialized" title="永久链接至目标"></a></dt>
<dd><p>如果 Python 解释器已初始化,则返回真值(非零);否则返回假值(零)。 在调用 <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> 之后,此函数将返回假值直到 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 再次被调用。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_FinalizeEx">
int <code class="sig-name descname">Py_FinalizeEx</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_FinalizeEx" title="永久链接至目标"></a></dt>
<dd><p>撤销 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 所做的所有初始化操作和后续对 Python/C API 函数的使用,并销毁自上次调用 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 以来创建但尚未销毁的所有子解释器(参见下文 <a class="reference internal" href="#c.Py_NewInterpreter" title="Py_NewInterpreter"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreter()</span></code></a> 一节)。 在理想情况下,这会释放 Python 解释器分配的所有内存。 当第二次调用时(在未再次调用 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 的情况下),这将不执行任何操作。 正常情况下返回值是 <code class="docutils literal notranslate"><span class="pre">0</span></code>。 如果在最终化(刷新缓冲数据)过程中出现错误,则返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code></p>
<p>提供此函数的原因有很多。嵌入应用程序可能希望重新启动Python而不必重新启动应用程序本身。从动态可加载库或DLL加载Python解释器的应用程序可能希望在卸载DLL之前释放Python分配的所有内存。在搜索应用程序内存泄漏的过程中开发人员可能希望在退出应用程序之前释放Python分配的所有内存。</p>
<p><strong>Bugs and caveats:</strong> The destruction of modules and objects in modules is done
in random order; this may cause destructors (<a class="reference internal" href="../reference/datamodel.html#object.__del__" title="object.__del__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__del__()</span></code></a> methods) to fail
when they depend on other objects (even functions) or modules. Dynamically
loaded extension modules loaded by Python are not unloaded. Small amounts of
memory allocated by the Python interpreter may not be freed (if you find a leak,
please report it). Memory tied up in circular references between objects is not
freed. Some memory allocated by extension modules may not be freed. Some
extensions may not work properly if their initialization routine is called more
than once; this can happen if an application calls <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> and
<a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> more than once.</p>
<p class="audit-hook">引发一个不带参数的 <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">审计事件</span></a> <code class="docutils literal notranslate"><span class="pre">cpython._PySys_ClearAuditHooks</span></code></p>
<div class="versionadded">
<p><span class="versionmodified added">3.6 新版功能.</span></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.Py_Finalize">
void <code class="sig-name descname">Py_Finalize</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_Finalize" title="永久链接至目标"></a></dt>
<dd><p>这是一个不考虑返回值的 <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> 的向下兼容版本。</p>
</dd></dl>
</section>
<section id="process-wide-parameters">
<h2>进程级参数<a class="headerlink" href="#process-wide-parameters" title="永久链接至标题"></a></h2>
<dl class="function">
<dt id="c.Py_SetStandardStreamEncoding">
int <code class="sig-name descname">Py_SetStandardStreamEncoding</code><span class="sig-paren">(</span>const char<em> *encoding</em>, const char<em> *errors</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_SetStandardStreamEncoding" title="永久链接至目标"></a></dt>
<dd><p id="index-17">如果要调用该函数,应当在 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 之前调用。 它指定了标准 IO 使用的编码格式和错误处理方式,其含义与 <a class="reference internal" href="../library/stdtypes.html#str.encode" title="str.encode"><code class="xref py py-func docutils literal notranslate"><span class="pre">str.encode()</span></code></a> 中的相同。</p>
<p>它覆盖了 <span class="target" id="index-82"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONIOENCODING"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONIOENCODING</span></code></a> 的值,并允许嵌入代码以便在环境变量不起作用时控制 IO 编码格式。</p>
<p><em>encoding</em> 和/或 <em>errors</em> 可以为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 以使用 <span class="target" id="index-83"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONIOENCODING"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONIOENCODING</span></code></a> 和/或默认值(取决于其他设置)。</p>
<p>请注意无论是否有此设置(或任何其他设置),<a class="reference internal" href="../library/sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a> 都会使用 &quot;backslashreplace&quot; 错误处理器。</p>
<p>如果调用了 <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a>,则需要再次调用该函数以便影响对 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 的后续调用。</p>
<p>成功时返回 <code class="docutils literal notranslate"><span class="pre">0</span></code>,出错时返回非零值(例如在解释器已被初始化后再调用)。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.Py_SetProgramName">
void <code class="sig-name descname">Py_SetProgramName</code><span class="sig-paren">(</span>const wchar_t<em> *name</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_SetProgramName" title="永久链接至目标"></a></dt>
<dd><p id="index-20">如果要调用该函数,应当在首次调用 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 之前调用它。 它将告诉解释器程序的 <code class="xref c c-func docutils literal notranslate"><span class="pre">main()</span></code> 函数的 <code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> 参数的值(转换为宽字符)。 <a class="reference internal" href="#c.Py_GetPath" title="Py_GetPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPath()</span></code></a> 和下面的某些其他函数会使用它在相对于解释器的位置上查找可执行文件的 Python 运行时库。 默认值是 <code class="docutils literal notranslate"><span class="pre">'python'</span></code>。 参数应当指向静态存储中的一个以零值结束的宽字符串,其内容在程序执行期间不会发生改变。 Python 解释器中的任何代码都不会改变该存储的内容。</p>
<p>Use <a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a> to decode a bytes string to get a
<code class="xref c c-type docutils literal notranslate"><span class="pre">wchar_*</span></code> string.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetProgramName">
wchar* <code class="sig-name descname">Py_GetProgramName</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetProgramName" title="永久链接至目标"></a></dt>
<dd><p id="index-21">返回用 <a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> 设置的程序名称,或默认的名称。 返回的字符串指向静态存储;调用者不应修改其值。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetPrefix">
wchar_t* <code class="sig-name descname">Py_GetPrefix</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetPrefix" title="永久链接至目标"></a></dt>
<dd><p>Return the <em>prefix</em> for installed platform-independent files. This is derived
through a number of complicated rules from the program name set with
<a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> and some environment variables; for example, if the
program name is <code class="docutils literal notranslate"><span class="pre">'/usr/local/bin/python'</span></code>, the prefix is <code class="docutils literal notranslate"><span class="pre">'/usr/local'</span></code>. The
returned string points into static storage; the caller should not modify its
value. This corresponds to the <strong class="makevar">prefix</strong> variable in the top-level
<code class="file docutils literal notranslate"><span class="pre">Makefile</span></code> and the <code class="docutils literal notranslate"><span class="pre">--prefix</span></code> argument to the <strong class="program">configure</strong>
script at build time. The value is available to Python code as <code class="docutils literal notranslate"><span class="pre">sys.prefix</span></code>.
It is only useful on Unix. See also the next function.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetExecPrefix">
wchar_t* <code class="sig-name descname">Py_GetExecPrefix</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetExecPrefix" title="永久链接至目标"></a></dt>
<dd><p>返回针对已安装的 <em>依赖于</em> 平台文件的 <em>exec-prefix</em>。 这是通过基于使用 <a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> 设置的程序名称和某些环境变量所派生的一系列复杂规则获得的;举例来说,如果程序名称为 <code class="docutils literal notranslate"><span class="pre">'/usr/local/bin/python'</span></code>,则 exec-prefix 为 <code class="docutils literal notranslate"><span class="pre">'/usr/local'</span></code>。 返回的字符串将指向静态存储;调用方不应修改其值。 这对应于最高层级 <code class="file docutils literal notranslate"><span class="pre">Makefile</span></code> 中的 <strong class="makevar">exec_prefix</strong> 变量以及在编译时传给 <strong class="program">configure</strong> 脚本的 <code class="docutils literal notranslate"><span class="pre">--exec-prefix</span></code> 参数。 该值将以 <code class="docutils literal notranslate"><span class="pre">sys.exec_prefix</span></code> 的名称供 Python 代码使用。 它仅适用于 Unix。</p>
<p>背景:当依赖于平台的文件(如可执行文件和共享库)是安装于不同的目录树中的时候 exec-prefix 将会不同于 prefix。 在典型的安装中,依赖于平台的文件可能安装于 the <code class="file docutils literal notranslate"><span class="pre">/usr/local/plat</span></code> 子目录树而独立于平台的文件可能安装于 <code class="file docutils literal notranslate"><span class="pre">/usr/local</span></code></p>
<p>总而言之,平台是一组硬件和软件资源的组合,例如所有运行 Solaris 2.x 操作系统的 Sparc 机器会被视为相同平台,但运行 Solaris 2.x 的 Intel 机器是另一种平台,而运行 Linux 的 Intel 机器又是另一种平台。 相同操作系统的不同主要发布版通常也会构成不同的平台。 非 Unix 操作系统的情况又有所不同;这类系统上的安装策略差别巨大因此 prefix 和 exec-prefix 是没有意义的,并将被设为空字符串。 请注意已编译的 Python 字节码是独立于平台的(但并不独立于它们编译时所使用的 Python 版本!)</p>
<p>系统管理员知道如何配置 <strong class="program">mount</strong><strong class="program">automount</strong> 程序以在平台间共享 <code class="file docutils literal notranslate"><span class="pre">/usr/local</span></code> 而让 <code class="file docutils literal notranslate"><span class="pre">/usr/local/plat</span></code> 成为针对不同平台的不同文件系统。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetProgramFullPath">
wchar_t* <code class="sig-name descname">Py_GetProgramFullPath</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetProgramFullPath" title="永久链接至目标"></a></dt>
<dd><p id="index-22">返回 Python 可执行文件的完整程序名称;这是作为根据程序名称(由上述 <a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> 设置)派生默认模块搜索路径的附带影响计算得出的。 返回的字符串将指向静态存储;调用方不应修改其值。 该值将以 <code class="docutils literal notranslate"><span class="pre">sys.executable</span></code> 的名称供 Python 代码使用。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetPath">
wchar_t* <code class="sig-name descname">Py_GetPath</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetPath" title="永久链接至目标"></a></dt>
<dd><p id="index-23">Return the default module search path; this is computed from the program name
(set by <a class="reference internal" href="#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> above) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is <code class="docutils literal notranslate"><span class="pre">':'</span></code>
on Unix and Mac OS X, <code class="docutils literal notranslate"><span class="pre">';'</span></code> on Windows. The returned string points into
static storage; the caller should not modify its value. The list
<a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> is initialized with this value on interpreter startup; it
can be (and usually is) modified later to change the search path for loading
modules.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_SetPath">
void <code class="sig-name descname">Py_SetPath</code><span class="sig-paren">(</span>const wchar_t<em> *</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_SetPath" title="永久链接至目标"></a></dt>
<dd><p id="index-24">Set the default module search path. If this function is called before
<a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>, then <a class="reference internal" href="#c.Py_GetPath" title="Py_GetPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetPath()</span></code></a> won't attempt to compute a
default search path but uses the one provided instead. This is useful if
Python is embedded by an application that has full knowledge of the location
of all modules. The path components should be separated by the platform
dependent delimiter character, which is <code class="docutils literal notranslate"><span class="pre">':'</span></code> on Unix and Mac OS X, <code class="docutils literal notranslate"><span class="pre">';'</span></code>
on Windows.</p>
<p>这也将导致 <a class="reference internal" href="../library/sys.html#sys.executable" title="sys.executable"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.executable</span></code></a> 被设为程序的完整路径 (参见 <a class="reference internal" href="#c.Py_GetProgramFullPath" title="Py_GetProgramFullPath"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_GetProgramFullPath()</span></code></a>) 而 <a class="reference internal" href="../library/sys.html#sys.prefix" title="sys.prefix"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.prefix</span></code></a><a class="reference internal" href="../library/sys.html#sys.exec_prefix" title="sys.exec_prefix"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.exec_prefix</span></code></a> 变为空值。 如果在调用 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 之后有需要则应由调用方来修改它们。</p>
<p>Use <a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a> to decode a bytes string to get a
<code class="xref c c-type docutils literal notranslate"><span class="pre">wchar_*</span></code> string.</p>
<p>路径参数会在内部被复制,使调用方可以在调用结束后释放它。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>现在 <a class="reference internal" href="../library/sys.html#sys.executable" title="sys.executable"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.executable</span></code></a> 将使用程序的完整路径,而不是程序文件名。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetVersion">
const char* <code class="sig-name descname">Py_GetVersion</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetVersion" title="永久链接至目标"></a></dt>
<dd><p>返回 Python 解释器的版本。 这将为如下形式的字符串</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="s">&quot;3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) </span><span class="se">\n</span><span class="s">[GCC 4.2.3]&quot;</span>
</pre></div>
</div>
<p id="index-25">The first word (up to the first space character) is the current Python version;
the first three characters are the major and minor version separated by a
period. The returned string points into static storage; the caller should not
modify its value. The value is available to Python code as <a class="reference internal" href="../library/sys.html#sys.version" title="sys.version"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.version</span></code></a>.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetPlatform">
const char* <code class="sig-name descname">Py_GetPlatform</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetPlatform" title="永久链接至目标"></a></dt>
<dd><p id="index-26">Return the platform identifier for the current platform. On Unix, this is
formed from the &quot;official&quot; name of the operating system, converted to lower
case, followed by the major revision number; e.g., for Solaris 2.x, which is
also known as SunOS 5.x, the value is <code class="docutils literal notranslate"><span class="pre">'sunos5'</span></code>. On Mac OS X, it is
<code class="docutils literal notranslate"><span class="pre">'darwin'</span></code>. On Windows, it is <code class="docutils literal notranslate"><span class="pre">'win'</span></code>. The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as <code class="docutils literal notranslate"><span class="pre">sys.platform</span></code>.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetCopyright">
const char* <code class="sig-name descname">Py_GetCopyright</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetCopyright" title="永久链接至目标"></a></dt>
<dd><p>返回当前 Python 版本的官方版权字符串,例如</p>
<p><code class="docutils literal notranslate"><span class="pre">'Copyright</span> <span class="pre">1991-1995</span> <span class="pre">Stichting</span> <span class="pre">Mathematisch</span> <span class="pre">Centrum,</span> <span class="pre">Amsterdam'</span></code></p>
<p id="index-27">返回的字符串指向静态存储;调用者不应修改其值。 Python 代码可通过 <code class="docutils literal notranslate"><span class="pre">sys.copyright</span></code> 获取该值。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetCompiler">
const char* <code class="sig-name descname">Py_GetCompiler</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetCompiler" title="永久链接至目标"></a></dt>
<dd><p>返回用于编译当前 Python 版本的编译器指令,为带方括号的形式,例如:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="s">&quot;[GCC 2.7.2.2]&quot;</span>
</pre></div>
</div>
<p id="index-28">返回的字符串指向静态存储;调用者不应修改其值。 Python 代码可以从变量 <code class="docutils literal notranslate"><span class="pre">sys.version</span></code> 中获取该值。</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetBuildInfo">
const char* <code class="sig-name descname">Py_GetBuildInfo</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetBuildInfo" title="永久链接至目标"></a></dt>
<dd><p>返回有关当前Python解释器实例的序列号和构建日期和时间的信息例如</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="s">&quot;#67, Aug 1 1997, 22:34:28&quot;</span>
</pre></div>
</div>
<p id="index-29">返回的字符串指向静态存储;调用者不应修改其值。 Python 代码可以从变量 <code class="docutils literal notranslate"><span class="pre">sys.version</span></code> 中获取该值。</p>
</dd></dl>
<dl class="function">
<dt id="c.PySys_SetArgvEx">
void <code class="sig-name descname">PySys_SetArgvEx</code><span class="sig-paren">(</span>int<em> argc</em>, wchar_t<em> **argv</em>, int<em> updatepath</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PySys_SetArgvEx" title="永久链接至目标"></a></dt>
<dd><p id="index-30">根据 <em>argc</em><em>argv</em> 设置 <a class="reference internal" href="../library/sys.html#sys.argv" title="sys.argv"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.argv</span></code></a>。 这些形参与传给程序的 <code class="xref c c-func docutils literal notranslate"><span class="pre">main()</span></code> 函数的类似,区别在于第一项应当指向要执行的脚本文件而不是 Python 解释器对应的可执行文件。 如果没有要运行的脚本,则 <em>argv</em> 中的第一项可以为空字符串。 如果此函数无法初始化 <a class="reference internal" href="../library/sys.html#sys.argv" title="sys.argv"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.argv</span></code></a>,则将使用 <a class="reference internal" href="sys.html#c.Py_FatalError" title="Py_FatalError"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FatalError()</span></code></a> 发出严重情况信号。</p>
<p>如果 <em>updatepath</em> 为零,此函数将完成操作。 如果 <em>updatepath</em> 为非零值,则此函数还将根据以下算法修改 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a>:</p>
<ul class="simple">
<li><p>如果在 <code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> 中传入一个现有脚本,则脚本所在目录的绝对路径将被添加到 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 的开头。</p></li>
<li><p>在其他情况下 (也就是说,如果 <em>argc</em><code class="docutils literal notranslate"><span class="pre">0</span></code><code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> 未指向现有文件名),则将在 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 的开头添加一个空字符串,这等价于添加当前工作目录 (<code class="docutils literal notranslate"><span class="pre">&quot;.&quot;</span></code>)。</p></li>
</ul>
<p>Use <a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a> to decode a bytes string to get a
<code class="xref c c-type docutils literal notranslate"><span class="pre">wchar_*</span></code> string.</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>建议在出于执行单个脚本以外的目的嵌入 Python 解释器的应用程序传入 <code class="docutils literal notranslate"><span class="pre">0</span></code> 作为 <em>updatepath</em>,并在需要时更新 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 本身。 参见 <a class="reference external" href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983">CVE-2008-5983</a></p>
<p>在 3.1.3 之前的版本中,你可以通过在调用 <a class="reference internal" href="#c.PySys_SetArgv" title="PySys_SetArgv"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_SetArgv()</span></code></a> 之后手动弹出第一个 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 元素,例如使用:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyRun_SimpleString</span><span class="p">(</span><span class="s">&quot;import sys; sys.path.pop(0)</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.1.3 新版功能.</span></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PySys_SetArgv">
void <code class="sig-name descname">PySys_SetArgv</code><span class="sig-paren">(</span>int<em> argc</em>, wchar_t<em> **argv</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PySys_SetArgv" title="永久链接至目标"></a></dt>
<dd><p>此函数相当于 <a class="reference internal" href="#c.PySys_SetArgvEx" title="PySys_SetArgvEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_SetArgvEx()</span></code></a> 设置了 <em>updatepath</em><code class="docutils literal notranslate"><span class="pre">1</span></code> 除非 <strong class="program">python</strong> 解释器启动时附带了 <a class="reference internal" href="../using/cmdline.html#id2"><code class="xref std std-option docutils literal notranslate"><span class="pre">-I</span></code></a></p>
<p>Use <a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a> to decode a bytes string to get a
<code class="xref c c-type docutils literal notranslate"><span class="pre">wchar_*</span></code> string.</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span><em>updatepath</em> 值依赖于 <a class="reference internal" href="../using/cmdline.html#id2"><code class="xref std std-option docutils literal notranslate"><span class="pre">-I</span></code></a></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.Py_SetPythonHome">
void <code class="sig-name descname">Py_SetPythonHome</code><span class="sig-paren">(</span>const wchar_t<em> *home</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_SetPythonHome" title="永久链接至目标"></a></dt>
<dd><p>设置默认的 &quot;home&quot; 目录,也就是标准 Python 库所在的位置。 请参阅 <span class="target" id="index-84"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONHOME"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONHOME</span></code></a> 了解该参数字符串的含义。</p>
<p>此参数应当指向静态存储中一个以零值结束的字符串,其内容在程序执行期间将保持不变。 Python 解释器中的代码绝不会修改此存储中的内容。</p>
<p>Use <a class="reference internal" href="sys.html#c.Py_DecodeLocale" title="Py_DecodeLocale"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DecodeLocale()</span></code></a> to decode a bytes string to get a
<code class="xref c c-type docutils literal notranslate"><span class="pre">wchar_*</span></code> string.</p>
</dd></dl>
<dl class="function">
<dt id="c.Py_GetPythonHome">
w_char* <code class="sig-name descname">Py_GetPythonHome</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_GetPythonHome" title="永久链接至目标"></a></dt>
<dd><p>返回默认的 &quot;home&quot;,就是由之前对 <a class="reference internal" href="#c.Py_SetPythonHome" title="Py_SetPythonHome"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetPythonHome()</span></code></a> 的调用所设置的值,或者在设置了 <span class="target" id="index-85"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONHOME"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONHOME</span></code></a> 环境变量的情况下该环境变量的值。</p>
</dd></dl>
</section>
<section id="thread-state-and-the-global-interpreter-lock">
<span id="threads"></span><h2>线程状态和全局解释器锁<a class="headerlink" href="#thread-state-and-the-global-interpreter-lock" title="永久链接至标题"></a></h2>
<p id="index-33">Python 解释器不是完全线程安全的。 为了支持多线程的 Python 程序,设置了一个全局锁,称为 <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a><a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a>,当前线程必须在持有它之后才能安全地访问 Python 对象。 如果没有这个锁,即使最简单的操作也可能在多线程的程序中导致问题:例如,当两个线程同时增加相同对象的引用计数时,引用计数可能最终只增加了一次而不是两次。</p>
<p id="index-34">因此,规则要求只有获得 <a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a> 的线程才能在 Python对象上执行操作或调用 Python/C API 函数。 为了模拟并发执行,解释器会定期尝试切换线程 (参见 <a class="reference internal" href="../library/sys.html#sys.setswitchinterval" title="sys.setswitchinterval"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.setswitchinterval()</span></code></a>)。 锁也会在读写文件等可能造成阻塞的 I/O 操作时释放,以便其他 Python 线程可以同时运行。</p>
<p id="index-35">Python 解释器会在一个名为 <a class="reference internal" href="#c.PyThreadState" title="PyThreadState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyThreadState</span></code></a> 的数据结构体中保存一些线程专属的记录信息。 还有一个全局变量指向当前的 <a class="reference internal" href="#c.PyThreadState" title="PyThreadState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyThreadState</span></code></a>: 它可以使用 <a class="reference internal" href="#c.PyThreadState_Get" title="PyThreadState_Get"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThreadState_Get()</span></code></a> 来获取。</p>
<section id="releasing-the-gil-from-extension-code">
<h3>从扩展扩展代码中释放 GIL<a class="headerlink" href="#releasing-the-gil-from-extension-code" title="永久链接至标题"></a></h3>
<p>大多数操作 <a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a> 的扩展代码具有以下简单结构:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Save</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="kr">thread</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">local</span><span class="w"> </span><span class="n">variable</span><span class="p">.</span>
<span class="n">Release</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">global</span><span class="w"> </span><span class="n">interpreter</span><span class="w"> </span><span class="n">lock</span><span class="p">.</span>
<span class="p">...</span><span class="w"> </span><span class="n">Do</span><span class="w"> </span><span class="n">some</span><span class="w"> </span><span class="n">blocking</span><span class="w"> </span><span class="n">I</span><span class="o">/</span><span class="n">O</span><span class="w"> </span><span class="n">operation</span><span class="w"> </span><span class="p">...</span>
<span class="n">Reacquire</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">global</span><span class="w"> </span><span class="n">interpreter</span><span class="w"> </span><span class="n">lock</span><span class="p">.</span>
<span class="n">Restore</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="kr">thread</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">local</span><span class="w"> </span><span class="n">variable</span><span class="p">.</span>
</pre></div>
</div>
<p>这是如此常用因此增加了一对宏来简化它:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Py_BEGIN_ALLOW_THREADS</span>
<span class="p">...</span><span class="w"> </span><span class="n">Do</span><span class="w"> </span><span class="n">some</span><span class="w"> </span><span class="n">blocking</span><span class="w"> </span><span class="n">I</span><span class="o">/</span><span class="n">O</span><span class="w"> </span><span class="n">operation</span><span class="w"> </span><span class="p">...</span>
<span class="n">Py_END_ALLOW_THREADS</span>
</pre></div>
</div>
<p id="index-36"><a class="reference internal" href="#c.Py_BEGIN_ALLOW_THREADS" title="Py_BEGIN_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_ALLOW_THREADS</span></code></a> 宏将打开一个新块并声明一个隐藏的局部变量;<a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS</span></code></a> 宏将关闭这个块。</p>
<p>上面的代码块可扩展为下面的代码:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyThreadState</span><span class="w"> </span><span class="o">*</span><span class="n">_save</span><span class="p">;</span>
<span class="n">_save</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyEval_SaveThread</span><span class="p">();</span>
<span class="p">...</span><span class="w"> </span><span class="n">Do</span><span class="w"> </span><span class="n">some</span><span class="w"> </span><span class="n">blocking</span><span class="w"> </span><span class="n">I</span><span class="o">/</span><span class="n">O</span><span class="w"> </span><span class="n">operation</span><span class="w"> </span><span class="p">...</span>
<span class="n">PyEval_RestoreThread</span><span class="p">(</span><span class="n">_save</span><span class="p">);</span>
</pre></div>
</div>
<p id="index-37">这些函数的工作原理如下:全局解释器锁被用来保护指向当前线程状态的指针。 当释放锁并保存线程状态时,必须在锁被释放之前获取当前线程状态指针 (因为另一个线程可以立即获取锁并将自己的线程状态存储到全局变量中)。 相应地,当获取锁并恢复线程状态时,必须在存储线程状态指针之前先获取锁。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>调用系统 I/O 函数是释放 GIL 的最常见用例,但它在调用不需要访问 Python 对象的长期运行计算,比如针对内存缓冲区进行操作的压缩或加密函数之前也很有用。 举例来说,在对数据执行压缩或哈希操作时标准 <a class="reference internal" href="../library/zlib.html#module-zlib" title="zlib: Low-level interface to compression and decompression routines compatible with gzip."><code class="xref py py-mod docutils literal notranslate"><span class="pre">zlib</span></code></a><a class="reference internal" href="../library/hashlib.html#module-hashlib" title="hashlib: Secure hash and message digest algorithms."><code class="xref py py-mod docutils literal notranslate"><span class="pre">hashlib</span></code></a> 模块就会释放 GIL。</p>
</div>
</section>
<section id="non-python-created-threads">
<span id="gilstate"></span><h3>非Python创建的线程<a class="headerlink" href="#non-python-created-threads" title="永久链接至标题"></a></h3>
<p>当使用专门的 Python API<a class="reference internal" href="../library/threading.html#module-threading" title="threading: Thread-based parallelism."><code class="xref py py-mod docutils literal notranslate"><span class="pre">threading</span></code></a> 模块)创建线程时,会自动关联一个线程状态因而上面显示的代码是正确的。 但是,如果线程是用 C 创建的(例如由具有自己的线程管理的第三方库创建),它们就不持有 GIL 也没有对应的线程状态结构体。</p>
<p>如果你需要从这些线程调用 Python 代码(这通常会是上述第三方库所提供的回调 API 的一部分),你必须首先通过创建线程状态数据结构体向解释器注册这些线程,然后获取 GIL最后存储它们的线程状态指针这样你才能开始使用 Python/C API。 完成以上步骤后,你应当重置线程状态指针,释放 GIL最后释放线程状态数据结构体。</p>
<p><a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a><a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 函数会自动完成上述的所有操作。 从 C 线程调用到 Python 的典型方式如下:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyGILState_STATE</span><span class="w"> </span><span class="n">gstate</span><span class="p">;</span>
<span class="n">gstate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyGILState_Ensure</span><span class="p">();</span>
<span class="cm">/* Perform Python actions here. */</span>
<span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CallSomeFunction</span><span class="p">();</span>
<span class="cm">/* evaluate result or handle exception */</span>
<span class="cm">/* Release the thread. No Python API allowed beyond this point. */</span>
<span class="n">PyGILState_Release</span><span class="p">(</span><span class="n">gstate</span><span class="p">);</span>
</pre></div>
</div>
<p>Note that the <code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_*()</span></code> functions assume there is only one global
interpreter (created automatically by <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>). Python
supports the creation of additional interpreters (using
<a class="reference internal" href="#c.Py_NewInterpreter" title="Py_NewInterpreter"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreter()</span></code></a>), but mixing multiple interpreters and the
<code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_*()</span></code> API is unsupported.</p>
</section>
<section id="cautions-about-fork">
<span id="fork-and-threads"></span><h3>有关 fork() 的注意事项<a class="headerlink" href="#cautions-about-fork" title="永久链接至标题"></a></h3>
<p>有关线程的另一个需要注意的重要问题是它们在面对 C <code class="xref c c-func docutils literal notranslate"><span class="pre">fork()</span></code> 调用时的行为。 在大多数支持 <code class="xref c c-func docutils literal notranslate"><span class="pre">fork()</span></code> 的系统中,当一个进程执行 fork 之后将只有发出 fork 的线程存在。 这对需要如何处理锁以及CPython 的运行时内所有的存储状态都会有实质性的影响。</p>
<p>The fact that only the &quot;current&quot; thread remains
means any locks held by other threads will never be released. Python solves
this for <a class="reference internal" href="../library/os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.fork()</span></code></a> by acquiring the locks it uses internally before
the fork, and releasing them afterwards. In addition, it resets any
<a class="reference internal" href="../library/threading.html#lock-objects"><span class="std std-ref">锁对象</span></a> in the child. When extending or embedding Python, there
is no way to inform Python of additional (non-Python) locks that need to be
acquired before or reset after a fork. OS facilities such as
<code class="xref c c-func docutils literal notranslate"><span class="pre">pthread_atfork()</span></code> would need to be used to accomplish the same thing.
Additionally, when extending or embedding Python, calling <code class="xref c c-func docutils literal notranslate"><span class="pre">fork()</span></code>
directly rather than through <a class="reference internal" href="../library/os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.fork()</span></code></a> (and returning to or calling
into Python) may result in a deadlock by one of Python's internal locks
being held by a thread that is defunct after the fork.
<a class="reference internal" href="sys.html#c.PyOS_AfterFork_Child" title="PyOS_AfterFork_Child"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyOS_AfterFork_Child()</span></code></a> tries to reset the necessary locks, but is not
always able to.</p>
<p>所有其他线程都将结束这一事实也意味着 CPython 的运行时状态必须妥善清理,<a class="reference internal" href="../library/os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.fork()</span></code></a> 就是这样做的。 这意味着最终化归属于当前解释器的所有其他 <a class="reference internal" href="#c.PyThreadState" title="PyThreadState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyThreadState</span></code></a> 对象以及所有其他 <a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyInterpreterState</span></code></a> 对象。 由于这一点以及 <a class="reference internal" href="#sub-interpreter-support"><span class="std std-ref">&quot;main&quot; 解释器</span></a> 的特殊性质,<code class="xref c c-func docutils literal notranslate"><span class="pre">fork()</span></code> 应当只在该解释器 的 &quot;main&quot; 线程中被调用,而 CPython 全局运行时最初就是在该线程中初始化的。 只有当 <code class="xref c c-func docutils literal notranslate"><span class="pre">exec()</span></code> 将随后立即被调用的情况是唯一的例外。</p>
</section>
<section id="high-level-api">
<h3>高阶 API<a class="headerlink" href="#high-level-api" title="永久链接至标题"></a></h3>
<p>这些是在编写 C 扩展代码或在嵌入 Python 解释器时最常用的类型和函数:</p>
<dl class="type">
<dt id="c.PyInterpreterState">
<code class="sig-name descname">PyInterpreterState</code><a class="headerlink" href="#c.PyInterpreterState" title="永久链接至目标"></a></dt>
<dd><p>该数据结构代表多个合作线程所共享的状态。 属于同一解释器的线程将共享其模块管理以及其他一些内部条目。 该结构体中不包含公有成员。</p>
<p>最初归属于不同解释器的线程不会共享任何东西,但进程状态如可用内存、打开的文件描述符等等除外。 全局解释器锁也会被所有线程共享,无论它们归属于哪个解释器。</p>
</dd></dl>
<dl class="type">
<dt id="c.PyThreadState">
<code class="sig-name descname">PyThreadState</code><a class="headerlink" href="#c.PyThreadState" title="永久链接至目标"></a></dt>
<dd><p>This data structure represents the state of a single thread. The only public
data member is <code class="xref py py-attr docutils literal notranslate"><span class="pre">interp</span></code> (<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyInterpreterState</span> <span class="pre">*</span></code></a>), which points to
this thread's interpreter state.</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_InitThreads">
void <code class="sig-name descname">PyEval_InitThreads</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_InitThreads" title="永久链接至目标"></a></dt>
<dd><p id="index-38">Initialize and acquire the global interpreter lock. It should be called in the
main thread before creating a second thread or engaging in any other thread
operations such as <code class="docutils literal notranslate"><span class="pre">PyEval_ReleaseThread(tstate)</span></code>. It is not needed before
calling <a class="reference internal" href="#c.PyEval_SaveThread" title="PyEval_SaveThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SaveThread()</span></code></a> or <a class="reference internal" href="#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a>.</p>
<p>This is a no-op when called for a second time.</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>该函数现在由 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 调用,因此你无需再自行调用它。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.2 版更改: </span>此函数已不再被允许在 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 之前调用。</p>
</div>
<span class="target" id="index-39"></span></dd></dl>
<dl class="function">
<dt id="c.PyEval_ThreadsInitialized">
int <code class="sig-name descname">PyEval_ThreadsInitialized</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_ThreadsInitialized" title="永久链接至目标"></a></dt>
<dd><p>如果 <a class="reference internal" href="#c.PyEval_InitThreads" title="PyEval_InitThreads"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_InitThreads()</span></code></a> 已经被调用则返回非零值。 此函数可在不持有 GIL 的情况下被调用,因而可被用来避免在单线程运行时对加锁 API 的调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>现在 <a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a> 将由 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 来初始化。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_SaveThread">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyEval_SaveThread</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_SaveThread" title="永久链接至目标"></a></dt>
<dd><p>释放全局解释器锁 (如果已创建) 并将线程状态重置为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>,返回之前的线程状态 (不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>)。 如果锁已被创建,则当前线程必须已获取到它。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_RestoreThread">
void <code class="sig-name descname">PyEval_RestoreThread</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_RestoreThread" title="永久链接至目标"></a></dt>
<dd><p>获取全局解释器锁 (如果已创建) 并将线程状态设为 <em>tstate</em>,它必须不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>。 如果锁已被创建,则当前线程必须尚未获取它,否则将发生死锁。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>当运行时正在最终化时从某个线程调用此函数将终结该线程,即使线程不是由 Python 创建的。 你可以在调用此函数之前使用 <code class="xref c c-func docutils literal notranslate"><span class="pre">_Py_IsFinalizing()</span></code><a class="reference internal" href="../library/sys.html#sys.is_finalizing" title="sys.is_finalizing"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.is_finalizing()</span></code></a> 来检查解释器是否还处于最终化过程中以避免不必要的终结。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_Get">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyThreadState_Get</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Get" title="永久链接至目标"></a></dt>
<dd><p>返回当前线程状态。 全局解释器锁必须被持有。 在当前状态为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 时,这将发出一个致命错误 (这样调用方将无须检查是否为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>)。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_Swap">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyThreadState_Swap</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Swap" title="永久链接至目标"></a></dt>
<dd><p>交换当前线程状态与由参数 <em>tstate</em> (可能为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>) 给出的线程状态。 全局解释器锁必须被持有且未被释放。</p>
</dd></dl>
<p>下列函数使用线程级本地存储,并且不能兼容子解释器:</p>
<dl class="function">
<dt id="c.PyGILState_Ensure">
PyGILState_STATE <code class="sig-name descname">PyGILState_Ensure</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyGILState_Ensure" title="永久链接至目标"></a></dt>
<dd><p>确保当前线程已准备好调用 Python C API 而不管 Python 或全局解释器锁的当前状态如何。 只要每次调用都与 <a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 的调用相匹配就可以通过线程调用此函数任意多次。 一般来说,只要线程状态恢复到 Release() 之前的状态就可以在 <a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a><a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 调用之间使用其他与线程相关的 API。 例如,可以正常使用 <a class="reference internal" href="#c.Py_BEGIN_ALLOW_THREADS" title="Py_BEGIN_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_ALLOW_THREADS</span></code></a><a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS</span></code></a> 宏。</p>
<p>返回值是一个当 <a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 被调用时的线程状态的不透明“句柄”,并且必须被传递给 <a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 以确保 Python 处于相同状态。 虽然允许递归调用,但这些句柄 <em>不能</em> 被共享 —— 每次对 <a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 的单独调用都必须保存其对 <a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 的调用的句柄。</p>
<p>当该函数返回时,当前线程将持有 GIL 并能够调用任意 Python 代码。 执行失败将导致致命级错误。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>当运行时正在最终化时从某个线程调用此函数将终结该线程,即使线程不是由 Python 创建的。 你可以在调用此函数之前使用 <code class="xref c c-func docutils literal notranslate"><span class="pre">_Py_IsFinalizing()</span></code><a class="reference internal" href="../library/sys.html#sys.is_finalizing" title="sys.is_finalizing"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.is_finalizing()</span></code></a> 来检查解释器是否还处于最终化过程中以避免不必要的终结。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyGILState_Release">
void <code class="sig-name descname">PyGILState_Release</code><span class="sig-paren">(</span>PyGILState_STATE<span class="sig-paren">)</span><a class="headerlink" href="#c.PyGILState_Release" title="永久链接至目标"></a></dt>
<dd><p>释放之前获取的任何资源。 在此调用之后Python 的状态将与其在对相应 <a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 调用之前的一样(但是通常此状态对调用方来说将是未知的,对 GILState API 的使用也是如此)。</p>
<p><a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 的每次调用都必须与在同一线程上对 <a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> 的调用相匹配。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyGILState_GetThisThreadState">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyGILState_GetThisThreadState</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyGILState_GetThisThreadState" title="永久链接至目标"></a></dt>
<dd><p>获取此线程的当前线程状态。 如果当前线程上没有使用过 GILState API 则可以返回 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>。 请注意主线程总是会有这样一个线程状态,即使没有在主线程上执行过自动线程状态调用。 这主要是一个辅助/诊断函数。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyGILState_Check">
int <code class="sig-name descname">PyGILState_Check</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyGILState_Check" title="永久链接至目标"></a></dt>
<dd><p>如果当前线程持有 GIL 则返回 <code class="docutils literal notranslate"><span class="pre">1</span></code> 否则返回 <code class="docutils literal notranslate"><span class="pre">0</span></code>。 此函数可以随时从任何线程调用。 只有当它的 Python 线程状态已经初始化并且当前持有 GIL 时它才会返回 <code class="docutils literal notranslate"><span class="pre">1</span></code>。 这主要是一个辅助/诊断函数。 例如在回调上下文或内存分配函数中会很有用处,当知道 GIL 被锁定时可以允许调用方执行敏感的操作或是在其他情况下做出不同的行为。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
</dd></dl>
<p>以下的宏被使用时通常不带末尾分号;请在 Python 源代码发布包中查看示例用法。</p>
<dl class="macro">
<dt id="c.Py_BEGIN_ALLOW_THREADS">
<code class="sig-name descname">Py_BEGIN_ALLOW_THREADS</code><a class="headerlink" href="#c.Py_BEGIN_ALLOW_THREADS" title="永久链接至目标"></a></dt>
<dd><p>此宏会扩展为 <code class="docutils literal notranslate"><span class="pre">{</span> <span class="pre">PyThreadState</span> <span class="pre">*_save;</span> <span class="pre">_save</span> <span class="pre">=</span> <span class="pre">PyEval_SaveThread();</span></code>。 请注意它包含一个开头花括号;它必须与后面的 <a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS</span></code></a> 宏匹配。 有关此宏的进一步讨论请参阅上文。</p>
</dd></dl>
<dl class="macro">
<dt id="c.Py_END_ALLOW_THREADS">
<code class="sig-name descname">Py_END_ALLOW_THREADS</code><a class="headerlink" href="#c.Py_END_ALLOW_THREADS" title="永久链接至目标"></a></dt>
<dd><p>此宏扩展为 <code class="docutils literal notranslate"><span class="pre">PyEval_RestoreThread(_save);</span> <span class="pre">}</span></code>。 注意它包含一个右花括号;它必须与之前的 <a class="reference internal" href="#c.Py_BEGIN_ALLOW_THREADS" title="Py_BEGIN_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_ALLOW_THREADS</span></code></a> 宏匹配。 请参阅上文以进一步讨论此宏。</p>
</dd></dl>
<dl class="macro">
<dt id="c.Py_BLOCK_THREADS">
<code class="sig-name descname">Py_BLOCK_THREADS</code><a class="headerlink" href="#c.Py_BLOCK_THREADS" title="永久链接至目标"></a></dt>
<dd><p>这个宏扩展为 <code class="docutils literal notranslate"><span class="pre">PyEval_RestoreThread(_save);</span></code>: 它等价于没有关闭花括号的 <a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS</span></code></a></p>
</dd></dl>
<dl class="macro">
<dt id="c.Py_UNBLOCK_THREADS">
<code class="sig-name descname">Py_UNBLOCK_THREADS</code><a class="headerlink" href="#c.Py_UNBLOCK_THREADS" title="永久链接至目标"></a></dt>
<dd><p>这个宏扩展为 <code class="docutils literal notranslate"><span class="pre">_save</span> <span class="pre">=</span> <span class="pre">PyEval_SaveThread();</span></code>: 它等价于没有开始花括号和变量声明的 <a class="reference internal" href="#c.Py_BEGIN_ALLOW_THREADS" title="Py_BEGIN_ALLOW_THREADS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_ALLOW_THREADS</span></code></a></p>
</dd></dl>
</section>
<section id="low-level-api">
<h3>底层级 API<a class="headerlink" href="#low-level-api" title="永久链接至标题"></a></h3>
<p>下列所有函数都必须在 <a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 之后被调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span><a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 现在会初始化 <a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a></p>
</div>
<dl class="function">
<dt id="c.PyInterpreterState_New">
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a>* <code class="sig-name descname">PyInterpreterState_New</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_New" title="永久链接至目标"></a></dt>
<dd><p>创建一个新的解释器状态对象。 不需要持有全局解释器锁,但如果有必要序列化对此函数的调用则可能会持有。</p>
<p class="audit-hook">引发一个不带参数的 <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">审计事件</span></a> <code class="docutils literal notranslate"><span class="pre">cpython.PyInterpreterState_New</span></code></p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_Clear">
void <code class="sig-name descname">PyInterpreterState_Clear</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Clear" title="永久链接至目标"></a></dt>
<dd><p>重置解释器状态对象中的所有信息。 必须持有全局解释器锁。</p>
<p class="audit-hook">引发一个不带参数的 <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">审计事件</span></a> <code class="docutils literal notranslate"><span class="pre">cpython.PyInterpreterState_Clear</span></code></p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_Delete">
void <code class="sig-name descname">PyInterpreterState_Delete</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Delete" title="永久链接至目标"></a></dt>
<dd><p>销毁解释器状态对象。 不需要持有全局解释器锁。 解释器状态必须使用之前对 <a class="reference internal" href="#c.PyInterpreterState_Clear" title="PyInterpreterState_Clear"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyInterpreterState_Clear()</span></code></a> 的调用来重置。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_New">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyThreadState_New</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_New" title="永久链接至目标"></a></dt>
<dd><p>创建属于给定解释器对象的新线程状态对象。全局解释器锁不需要保持,但如果需要序列化对此函数的调用,则可以保持。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_Clear">
void <code class="sig-name descname">PyThreadState_Clear</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Clear" title="永久链接至目标"></a></dt>
<dd><p>重置线程状态对象中的所有信息。 必须持有全局解释器锁。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_Delete">
void <code class="sig-name descname">PyThreadState_Delete</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Delete" title="永久链接至目标"></a></dt>
<dd><p>销毁线程状态对象。 不需要持有全局解释器锁。 线程状态必须使用之前对 <a class="reference internal" href="#c.PyThreadState_Clear" title="PyThreadState_Clear"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThreadState_Clear()</span></code></a> 的调用来重置。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_GetID">
PY_INT64_T <code class="sig-name descname">PyInterpreterState_GetID</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_GetID" title="永久链接至目标"></a></dt>
<dd><p>返回解释器的唯一 ID。 如果执行过程中发生任何错误则将返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code> 并设置错误。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能.</span></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_GetDict">
<a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a>* <code class="sig-name descname">PyInterpreterState_GetDict</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_GetDict" title="永久链接至目标"></a></dt>
<dd><p>返回一个存储解释器专属数据的字典。 如果此函数返回 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 则没有任何异常被引发并且调用方应当将解释器专属字典视为不可用。</p>
<p>这不是 <a class="reference internal" href="module.html#c.PyModule_GetState" title="PyModule_GetState"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyModule_GetState()</span></code></a> 的替代,扩展仍应使用它来存储解释器专属的状态信息。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.8 新版功能.</span></p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_GetDict">
<a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a>* <code class="sig-name descname">PyThreadState_GetDict</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_GetDict" title="永久链接至目标"></a></dt>
<dd><em class="refcount">Return value: Borrowed reference.</em><p>返回一个扩展可以在其中存储线程专属状态信息的字典。 每个扩展都应当使用一个独有的键用来在该字典中存储状态。 在没有可用的当前线程状态时也可以调用此函数。 如果此函数返回 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>,则还没有任何异常被引发并且调用方应当假定没有可用的当前线程状态。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_SetAsyncExc">
int <code class="sig-name descname">PyThreadState_SetAsyncExc</code><span class="sig-paren">(</span>unsigned long<em> id</em>, <a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *exc</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_SetAsyncExc" title="永久链接至目标"></a></dt>
<dd><p>Asynchronously raise an exception in a thread. The <em>id</em> argument is the thread
id of the target thread; <em>exc</em> is the exception object to be raised. This
function does not steal any references to <em>exc</em>. To prevent naive misuse, you
must write your own C extension to call this. Must be called with the GIL held.
Returns the number of thread states modified; this is normally one, but will be
zero if the thread id isn't found. If <em>exc</em> is <code class="xref py py-const docutils literal notranslate"><span class="pre">NULL</span></code>, the pending
exception (if any) for the thread is cleared. This raises no exceptions.</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>The type of the <em>id</em> parameter changed from <code class="xref c c-type docutils literal notranslate"><span class="pre">long</span></code> to
<code class="xref c c-type docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span></code>.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_AcquireThread">
void <code class="sig-name descname">PyEval_AcquireThread</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_AcquireThread" title="永久链接至目标"></a></dt>
<dd><p>Acquire the global interpreter lock and set the current thread state to
<em>tstate</em>, which should not be <code class="docutils literal notranslate"><span class="pre">NULL</span></code>. The lock must have been created earlier.
If this thread already has the lock, deadlock ensues.</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>当运行时正在最终化时从某个线程调用此函数将终结该线程,即使线程不是由 Python 创建的。 你可以在调用此函数之前使用 <code class="xref c c-func docutils literal notranslate"><span class="pre">_Py_IsFinalizing()</span></code><a class="reference internal" href="../library/sys.html#sys.is_finalizing" title="sys.is_finalizing"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.is_finalizing()</span></code></a> 来检查解释器是否还处于最终化过程中以避免不必要的终结。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>已被更新为与 <a class="reference internal" href="#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a>, <a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS()</span></code></a><a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 保持一致,如果在解释器正在最终化时被调用则会终结当前线程。</p>
</div>
<p><a class="reference internal" href="#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a> 是一个始终可用的(即使线程尚未初始化)更高层级函数。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_ReleaseThread">
void <code class="sig-name descname">PyEval_ReleaseThread</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_ReleaseThread" title="永久链接至目标"></a></dt>
<dd><p>将当前线程状态重置为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 并释放全局解释器锁。 在此之前锁必须已被创建并且必须由当前的线程所持有。 <em>tstate</em> 参数必须不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>,该参数仅被用于检查它是否代表当前线程状态 --- 如果不是,则会报告一个致命级错误。</p>
<p><a class="reference internal" href="#c.PyEval_SaveThread" title="PyEval_SaveThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SaveThread()</span></code></a> 是一个始终可用的(即使线程尚未初始化)更高层级函数。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_AcquireLock">
void <code class="sig-name descname">PyEval_AcquireLock</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_AcquireLock" title="永久链接至目标"></a></dt>
<dd><p>获取全局解释器锁。锁必须在此之前已被创建。 如果该线程已经拥有锁,则会出现死锁。</p>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.2 版后已移除: </span>此函数不会更新当前线程状态。 请改用 <a class="reference internal" href="#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a><a class="reference internal" href="#c.PyEval_AcquireThread" title="PyEval_AcquireThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_AcquireThread()</span></code></a></p>
</div>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>当运行时正在最终化时从某个线程调用此函数将终结该线程,即使线程不是由 Python 创建的。 你可以在调用此函数之前使用 <code class="xref c c-func docutils literal notranslate"><span class="pre">_Py_IsFinalizing()</span></code><a class="reference internal" href="../library/sys.html#sys.is_finalizing" title="sys.is_finalizing"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.is_finalizing()</span></code></a> 来检查解释器是否还处于最终化过程中以避免不必要的终结。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>已被更新为与 <a class="reference internal" href="#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a>, <a class="reference internal" href="#c.Py_END_ALLOW_THREADS" title="Py_END_ALLOW_THREADS"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_END_ALLOW_THREADS()</span></code></a><a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> 保持一致,如果在解释器正在最终化时被调用则会终结当前线程。</p>
</div>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_ReleaseLock">
void <code class="sig-name descname">PyEval_ReleaseLock</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_ReleaseLock" title="永久链接至目标"></a></dt>
<dd><p>释放全局解释器锁。 锁必须在此之前已被创建。</p>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.2 版后已移除: </span>此函数不会更新当前线程状态。 请改用 <a class="reference internal" href="#c.PyEval_SaveThread" title="PyEval_SaveThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SaveThread()</span></code></a><a class="reference internal" href="#c.PyEval_ReleaseThread" title="PyEval_ReleaseThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_ReleaseThread()</span></code></a></p>
</div>
</dd></dl>
</section>
</section>
<section id="sub-interpreter-support">
<span id="id1"></span><h2>子解释器支持<a class="headerlink" href="#sub-interpreter-support" title="永久链接至标题"></a></h2>
<p>虽然在大多数用例中,你都只会嵌入一个单独的 Python 解释器,但某些场景需要你在同一个进程甚至同一个线程中创建多个独立的解释器。 子解释器让你能够做到这一点。</p>
<p>“主”解释器是在运行时初始化时创建的第一个解释器。 它通常是一个进程中唯一的 Python 解释器。 与子解释器不同,主解释器具有唯一的进程全局责任比如信号处理等。 它还负责在运行时初始化期间的执行并且通常还是运行时最终化期间的活动解释器。 <a class="reference internal" href="#c.PyInterpreterState_Main" title="PyInterpreterState_Main"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyInterpreterState_Main()</span></code></a> 函数将返回一个指向其状态的指针。</p>
<p>你可以使用 <a class="reference internal" href="#c.PyThreadState_Swap" title="PyThreadState_Swap"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThreadState_Swap()</span></code></a> 函数在子解释器之间进行切换。 你可以使用下列函数来创建和销毁它们:</p>
<dl class="function">
<dt id="c.Py_NewInterpreter">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">Py_NewInterpreter</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_NewInterpreter" title="永久链接至目标"></a></dt>
<dd><p id="index-40">新建一个子解释器。 这是一个 (几乎) 完全隔离的 Python 代码执行环境。 特别需要注意,新的子解释器具有全部已导入模块的隔离的、独立的版本,包括基本模块 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a>, <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a><a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a> 等。 已加载模块表 (<code class="docutils literal notranslate"><span class="pre">sys.modules</span></code>) 和模块搜索路径 (<code class="docutils literal notranslate"><span class="pre">sys.path</span></code>) 也是隔离的。 新环境没有 <code class="docutils literal notranslate"><span class="pre">sys.argv</span></code> 变量。 它具有新的标准 I/O 流文件对象 <code class="docutils literal notranslate"><span class="pre">sys.stdin</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.stdout</span></code><code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code> (不过这些对象都指向相同的底层文件描述符)。</p>
<p>The return value points to the first thread state created in the new
sub-interpreter. This thread state is made in the current thread state.
Note that no actual thread is created; see the discussion of thread states
below. If creation of the new interpreter is unsuccessful, <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is
returned; no exception is set since the exception state is stored in the
current thread state and there may not be a current thread state. (Like all
other Python/C API functions, the global interpreter lock must be held before
calling this function and is still held when it returns; however, unlike most
other Python/C API functions, there needn't be a current thread state on
entry.)</p>
<p id="index-41">扩展模块将以如下方式在(子)解释器之间共享:</p>
<ul>
<li><p>对于使用多阶段初始化的模块 ,例如 <a class="reference internal" href="module.html#c.PyModule_FromDefAndSpec" title="PyModule_FromDefAndSpec"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyModule_FromDefAndSpec()</span></code></a>,将为每个解释器创建并初始化一个单独的模块对象。 只有 C 层级的静态和全局变量能在这些模块 对象之间共享。</p></li>
<li><p>对于使用单阶段初始化的模块,例如 <a class="reference internal" href="module.html#c.PyModule_Create" title="PyModule_Create"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyModule_Create()</span></code></a>,当特定扩展被首次导入时,它将被正常初始化,并会保存其模块字典的一个 (浅) 拷贝。 当同一扩展被另一个 (子) 解释器导入时,将初始化一个新模块并填充该拷贝的内容;扩展的 <code class="docutils literal notranslate"><span class="pre">init</span></code> 函数不会被调用。 因此模块字典中的对象最终会被 (子) 解释器所共享,这可能会导致预期之外的行为 (参见下文的 <a class="reference internal" href="#bugs-and-caveats">Bugs and caveats</a>)。</p>
<p>请注意这不同于在调用 <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a><a class="reference internal" href="#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> 完全重新初始化解释器之后导入扩展时所发生的情况;对于那种情况,扩展的 <code class="docutils literal notranslate"><span class="pre">initmodule</span></code> 函数 <em>会被</em> 再次调用。 与多阶段初始化一样,这意味着只有 C 层级的静态和全局变量能在这些模块之间共享。</p>
</li>
</ul>
<span class="target" id="index-42"></span></dd></dl>
<dl class="function">
<dt id="c.Py_EndInterpreter">
void <code class="sig-name descname">Py_EndInterpreter</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_EndInterpreter" title="永久链接至目标"></a></dt>
<dd><p id="index-43">Destroy the (sub-)interpreter represented by the given thread state. The given
thread state must be the current thread state. See the discussion of thread
states below. When the call returns, the current thread state is <code class="docutils literal notranslate"><span class="pre">NULL</span></code>. All
thread states associated with this interpreter are destroyed. (The global
interpreter lock must be held before calling this function and is still held
when it returns.) <a class="reference internal" href="#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> will destroy all sub-interpreters that
haven't been explicitly destroyed at that point.</p>
</dd></dl>
<section id="bugs-and-caveats">
<h3>错误和警告<a class="headerlink" href="#bugs-and-caveats" title="永久链接至标题"></a></h3>
<p>由于子解释器 (以及主解释器) 都是同一个进程的组成部分,它们之间的隔离状态并非完美 --- 举例来说,使用低层级的文件操作如 <a class="reference internal" href="../library/os.html#os.close" title="os.close"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.close()</span></code></a> 时它们可能 (无意或恶意地) 影响它们各自打开的文件。 由于 (子) 解释器之间共享扩展的方式,某些扩展可能无法正常工作;在使用单阶段初始化或者 (静态) 全局变量时尤其如此。 在一个子解释器中创建的对象有可能被插入到另一个 (子) 解释器的命名空间中;这种情况应当尽可能地避免。</p>
<p>应当特别注意避免在子解释器之间共享用户自定义的函数、方法、实例或类,因为由这些对象执行的导入 操作可能会影响错误的已加载模块的 (子) 解释器的字典。 同样重要的一点是应当避免共享可被上述对象访问的对象 。</p>
<p>Also note that combining this functionality with <code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_*()</span></code> APIs
is delicate, because these APIs assume a bijection between Python thread states
and OS-level threads, an assumption broken by the presence of sub-interpreters.
It is highly recommended that you don't switch sub-interpreters between a pair
of matching <a class="reference internal" href="#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a> and <a class="reference internal" href="#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a> calls.
Furthermore, extensions (such as <a class="reference internal" href="../library/ctypes.html#module-ctypes" title="ctypes: A foreign function library for Python."><code class="xref py py-mod docutils literal notranslate"><span class="pre">ctypes</span></code></a>) using these APIs to allow calling
of Python code from non-Python created threads will probably be broken when using
sub-interpreters.</p>
</section>
</section>
<section id="asynchronous-notifications">
<h2>异步通知<a class="headerlink" href="#asynchronous-notifications" title="永久链接至标题"></a></h2>
<p>提供了一种向主解释器线程发送异步通知的机制。 这些通知将采用函数指针和空指针参数的形式。</p>
<dl class="function">
<dt id="c.Py_AddPendingCall">
int <code class="sig-name descname">Py_AddPendingCall</code><span class="sig-paren">(</span>int (<em>*func</em>)(void *), void<em> *arg</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_AddPendingCall" title="永久链接至目标"></a></dt>
<dd><p id="index-44">将一个函数加入从主解释器线程调用的计划任务。 成功时,将返回 <code class="docutils literal notranslate"><span class="pre">0</span></code> 并将 <em>func</em> 加入要被主线程调用的等待队列。 失败时,将返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code> 但不会设置任何异常。</p>
<p>当成功加入队列后,<em>func</em><em>最终</em> 附带参数 <em>arg</em> 被主解释器线程调用。 对于正常运行的 Python 代码来说它将被异步地调用,但要同时满足以下两个条件:</p>
<ul class="simple">
<li><p>位于 <a class="reference internal" href="../glossary.html#term-bytecode"><span class="xref std std-term">bytecode</span></a> 的边界上;</p></li>
<li><p>主线程持有 <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a> (因此 <em>func</em> 可以使用完整的 C API)。</p></li>
</ul>
<p><em>func</em> 必须在成功时返回 <code class="docutils literal notranslate"><span class="pre">0</span></code>,或在失败时返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code> 并设置一个异常集合。 <em>func</em> 不会被中断来递归地执行另一个异步通知,但如果全局解释器锁被释放则它仍可被中断以切换线程。</p>
<p>此函数的运行不需要当前线程状态,也不需要全局解释器锁。</p>
<div class="admonition warning">
<p class="admonition-title">警告</p>
<p>这是一个低层级函数,只在非常特殊的情况下有用。 不能保证 <em>func</em> 会尽快被调用。 如果主线程忙于执行某个系统调用,<em>func</em> 将不会在系统调用返回之前被调用。 此函数 通常 <strong>不适合</strong> 从任意 C 线程调用 Python 代码。 作为替代,请使用 <a class="reference internal" href="#gilstate"><span class="std std-ref">PyGILStateAPI</span></a></p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.1 新版功能.</span></p>
</div>
</dd></dl>
</section>
<section id="profiling-and-tracing">
<span id="profiling"></span><h2>分析和跟踪<a class="headerlink" href="#profiling-and-tracing" title="永久链接至标题"></a></h2>
<p>Python 解释器为附加的性能分析和执行跟踪工具提供了一些低层级的支持。 它们可被用于性能分析、调试和覆盖分析工具。</p>
<p>这个 C 接口允许性能分析或跟踪代码避免调用 Python 层级的可调用对象带来的开销,它能直接执行 C 函数调用。 此工具的基本属性没有变化;这个接口允许针对每个线程安装跟踪函数,并且向跟踪函数报告的基本事件与之前版本中向 Python 层级跟踪函数报告的事件相同。</p>
<dl class="type">
<dt id="c.Py_tracefunc">
int <code class="sig-name descname">(*Py_tracefunc)</code><span class="sig-paren">(</span><a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *obj</em>, <a class="reference internal" href="veryhigh.html#c.PyFrameObject" title="PyFrameObject">PyFrameObject</a><em> *frame</em>, int<em> what</em>, <a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *arg</em><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_tracefunc" title="永久链接至目标"></a></dt>
<dd><p>The type of the trace function registered using <a class="reference internal" href="#c.PyEval_SetProfile" title="PyEval_SetProfile"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SetProfile()</span></code></a> and
<a class="reference internal" href="#c.PyEval_SetTrace" title="PyEval_SetTrace"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SetTrace()</span></code></a>. The first parameter is the object passed to the
registration function as <em>obj</em>, <em>frame</em> is the frame object to which the event
pertains, <em>what</em> is one of the constants <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_CALL</span></code>,
<code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_EXCEPTION</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_LINE</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_RETURN</span></code>,
<code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_CALL</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_EXCEPTION</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_RETURN</span></code>,
or <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_OPCODE</span></code>, and <em>arg</em> depends on the value of <em>what</em>:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 43%" />
<col style="width: 57%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p><em>what</em> 的值</p></th>
<th class="head"><p><em>arg</em> 的含义</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_CALL</span></code></p></td>
<td><p>总是 <a class="reference internal" href="none.html#c.Py_None" title="Py_None"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_None</span></code></a>.</p></td>
</tr>
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_EXCEPTION</span></code></p></td>
<td><p><a class="reference internal" href="../library/sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.exc_info()</span></code></a> 返回的异常信息。</p></td>
</tr>
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_LINE</span></code></p></td>
<td><p>总是 <a class="reference internal" href="none.html#c.Py_None" title="Py_None"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_None</span></code></a>.</p></td>
</tr>
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_RETURN</span></code></p></td>
<td><p>返回给调用方的值,或者如果是由异常导致的则返回 <code class="docutils literal notranslate"><span class="pre">NULL</span></code></p></td>
</tr>
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_CALL</span></code></p></td>
<td><p>正在调用函数对象。</p></td>
</tr>
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_EXCEPTION</span></code></p></td>
<td><p>正在调用函数对象。</p></td>
</tr>
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_RETURN</span></code></p></td>
<td><p>正在调用函数对象。</p></td>
</tr>
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_OPCODE</span></code></p></td>
<td><p>总是 <a class="reference internal" href="none.html#c.Py_None" title="Py_None"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_None</span></code></a>.</p></td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_CALL">
int <code class="sig-name descname">PyTrace_CALL</code><a class="headerlink" href="#c.PyTrace_CALL" title="永久链接至目标"></a></dt>
<dd><p>当对一个函数或方法的新调用被报告,或是向一个生成器增加新条目时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。 请注意针对生成器函数的迭代器的创建情况不会被报告因为在相应的帧中没有向 Python字节码转移控制权。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_EXCEPTION">
int <code class="sig-name descname">PyTrace_EXCEPTION</code><a class="headerlink" href="#c.PyTrace_EXCEPTION" title="永久链接至目标"></a></dt>
<dd><p>当一个异常被引发时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。 在处理完任何字节码之后将附带 <em>what</em> 的值调用回调函数,在此之后该异常将会被设置在正在执行的帧中。 这样做的效果是当异常传播导致 Python 栈展开时,被调用的回调函数将随异常传播返回到每个帧。 只有跟踪函数才会接收到这些事件;性能分析器并不需要它们。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_LINE">
int <code class="sig-name descname">PyTrace_LINE</code><a class="headerlink" href="#c.PyTrace_LINE" title="永久链接至目标"></a></dt>
<dd><p>The value passed as the <em>what</em> parameter to a <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> function
(but not a profiling function) when a line-number event is being reported.
It may be disabled for a frame by setting <code class="xref py py-attr docutils literal notranslate"><span class="pre">f_trace_lines</span></code> to <em>0</em> on that frame.</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_RETURN">
int <code class="sig-name descname">PyTrace_RETURN</code><a class="headerlink" href="#c.PyTrace_RETURN" title="永久链接至目标"></a></dt>
<dd><p>当一个调用即将返回时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_C_CALL">
int <code class="sig-name descname">PyTrace_C_CALL</code><a class="headerlink" href="#c.PyTrace_C_CALL" title="永久链接至目标"></a></dt>
<dd><p>当一个 C 函数即将被调用时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_C_EXCEPTION">
int <code class="sig-name descname">PyTrace_C_EXCEPTION</code><a class="headerlink" href="#c.PyTrace_C_EXCEPTION" title="永久链接至目标"></a></dt>
<dd><p>当一个 C 函数引发异常时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_C_RETURN">
int <code class="sig-name descname">PyTrace_C_RETURN</code><a class="headerlink" href="#c.PyTrace_C_RETURN" title="永久链接至目标"></a></dt>
<dd><p>当一个 C 函数返回时传给 <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> 函数的 <em>what</em> 形参的值。</p>
</dd></dl>
<dl class="var">
<dt id="c.PyTrace_OPCODE">
int <code class="sig-name descname">PyTrace_OPCODE</code><a class="headerlink" href="#c.PyTrace_OPCODE" title="永久链接至目标"></a></dt>
<dd><p>The value for the <em>what</em> parameter to <a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tracefunc</span></code></a> functions (but not
profiling functions) when a new opcode is about to be executed. This event is
not emitted by default: it must be explicitly requested by setting
<code class="xref py py-attr docutils literal notranslate"><span class="pre">f_trace_opcodes</span></code> to <em>1</em> on the frame.</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_SetProfile">
void <code class="sig-name descname">PyEval_SetProfile</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc">Py_tracefunc</a><em> func</em>, <a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *obj</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_SetProfile" title="永久链接至目标"></a></dt>
<dd><p>Set the profiler function to <em>func</em>. The <em>obj</em> parameter is passed to the
function as its first parameter, and may be any Python object, or <code class="docutils literal notranslate"><span class="pre">NULL</span></code>. If
the profile function needs to maintain state, using a different value for <em>obj</em>
for each thread provides a convenient and thread-safe place to store it. The
profile function is called for all monitored events except <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_LINE</span></code>
<code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_OPCODE</span></code> and <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_EXCEPTION</span></code>.</p>
</dd></dl>
<dl class="function">
<dt id="c.PyEval_SetTrace">
void <code class="sig-name descname">PyEval_SetTrace</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tracefunc" title="Py_tracefunc">Py_tracefunc</a><em> func</em>, <a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *obj</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyEval_SetTrace" title="永久链接至目标"></a></dt>
<dd><p>Set the tracing function to <em>func</em>. This is similar to
<a class="reference internal" href="#c.PyEval_SetProfile" title="PyEval_SetProfile"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SetProfile()</span></code></a>, except the tracing function does receive line-number
events and per-opcode events, but does not receive any event related to C function
objects being called. Any trace function registered using <a class="reference internal" href="#c.PyEval_SetTrace" title="PyEval_SetTrace"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SetTrace()</span></code></a>
will not receive <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_CALL</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_EXCEPTION</span></code> or
<code class="xref py py-const docutils literal notranslate"><span class="pre">PyTrace_C_RETURN</span></code> as a value for the <em>what</em> parameter.</p>
</dd></dl>
</section>
<section id="advanced-debugger-support">
<span id="advanced-debugging"></span><h2>高级调试器支持<a class="headerlink" href="#advanced-debugger-support" title="永久链接至标题"></a></h2>
<p>这些函数仅供高级调试工具使用。</p>
<dl class="function">
<dt id="c.PyInterpreterState_Head">
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a>* <code class="sig-name descname">PyInterpreterState_Head</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Head" title="永久链接至目标"></a></dt>
<dd><p>将解释器状态对象返回到由所有此类对象组成的列表的开头。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_Main">
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a>* <code class="sig-name descname">PyInterpreterState_Main</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Main" title="永久链接至目标"></a></dt>
<dd><p>返回主解释器状态对象。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_Next">
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a>* <code class="sig-name descname">PyInterpreterState_Next</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Next" title="永久链接至目标"></a></dt>
<dd><p>从由解释器状态对象组成的列表中返回 <em>interp</em> 之后的下一项。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyInterpreterState_ThreadHead">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a> * <code class="sig-name descname">PyInterpreterState_ThreadHead</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState">PyInterpreterState</a><em> *interp</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_ThreadHead" title="永久链接至目标"></a></dt>
<dd><p>在由与解释器 <em>interp</em> 相关联的线程组成的列表中返回指向第一个 <a class="reference internal" href="#c.PyThreadState" title="PyThreadState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyThreadState</span></code></a> 对象的指针。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThreadState_Next">
<a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a>* <code class="sig-name descname">PyThreadState_Next</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThreadState" title="PyThreadState">PyThreadState</a><em> *tstate</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Next" title="永久链接至目标"></a></dt>
<dd><p>从由属于同一个 <a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyInterpreterState</span></code></a> 对象的线程状态对象组成的列表中返回 <em>tstate</em> 之后的下一项。</p>
</dd></dl>
</section>
<section id="thread-local-storage-support">
<span id="thread-local-storage"></span><h2>线程本地存储支持<a class="headerlink" href="#thread-local-storage-support" title="永久链接至标题"></a></h2>
<p>The Python interpreter provides low-level support for thread-local storage
(TLS) which wraps the underlying native TLS implementation to support the
Python-level thread local storage API (<a class="reference internal" href="../library/threading.html#threading.local" title="threading.local"><code class="xref py py-class docutils literal notranslate"><span class="pre">threading.local</span></code></a>). The
CPython C level APIs are similar to those offered by pthreads and Windows:
use a thread key and functions to associate a <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> value per
thread.</p>
<p>当调用这些函数时 <em>无须</em> 持有 GIL它们会提供自己的锁机制。</p>
<p>请注意 <code class="file docutils literal notranslate"><span class="pre">Python.h</span></code> 并不包括 TLS API 的声明,你需要包括 <code class="file docutils literal notranslate"><span class="pre">pythread.h</span></code> 来使用线程本地存储。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>None of these API functions handle memory management on behalf of the
<code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> values. You need to allocate and deallocate them yourself.
If the <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> values happen to be <a class="reference internal" href="structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject*</span></code></a>, these
functions don't do refcount operations on them either.</p>
</div>
<section id="thread-specific-storage-tss-api">
<span id="thread-specific-storage-api"></span><h3>线程专属存储 (TSS) API<a class="headerlink" href="#thread-specific-storage-tss-api" title="永久链接至标题"></a></h3>
<p>TSS API is introduced to supersede the use of the existing TLS API within the
CPython interpreter. This API uses a new type <a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tss_t</span></code></a> instead of
<code class="xref c c-type docutils literal notranslate"><span class="pre">int</span></code> to represent thread keys.</p>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能.</span></p>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p>&quot;A New C-API for Thread-Local Storage in CPython&quot; (<span class="target" id="index-45"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0539"><strong>PEP 539</strong></a>)</p>
</div>
<dl class="type">
<dt id="c.Py_tss_t">
<code class="sig-name descname">Py_tss_t</code><a class="headerlink" href="#c.Py_tss_t" title="永久链接至目标"></a></dt>
<dd><p>该数据结构表示线程键的状态,其定义可能依赖于下层的 TLS 实现,并且它有一个表示键初始化状态的内部字段。 该结构体中不存在公有成员。</p>
<p>当未定义 <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Py_LIMITED_API</span></a> 时,允许由 <a class="reference internal" href="#c.Py_tss_NEEDS_INIT" title="Py_tss_NEEDS_INIT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_tss_NEEDS_INIT</span></code></a> 执行此类型的静态分配。</p>
</dd></dl>
<dl class="macro">
<dt id="c.Py_tss_NEEDS_INIT">
<code class="sig-name descname">Py_tss_NEEDS_INIT</code><a class="headerlink" href="#c.Py_tss_NEEDS_INIT" title="永久链接至目标"></a></dt>
<dd><p>这个宏将扩展为 <a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tss_t</span></code></a> 变量的初始化器。 请注意这个宏不会用 <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Py_LIMITED_API</span></a> 来定义。</p>
</dd></dl>
<section id="dynamic-allocation">
<h4>动态分配<a class="headerlink" href="#dynamic-allocation" title="永久链接至标题"></a></h4>
<p><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tss_t</span></code></a> 的动态分配,在使用 <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Py_LIMITED_API</span></a> 编译的扩展模块中是必须的,在这些模块由于此类型的实现在编译时是不透明的因此它不可能静态分配。</p>
<dl class="function">
<dt id="c.PyThread_tss_alloc">
<a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a>* <code class="sig-name descname">PyThread_tss_alloc</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_alloc" title="永久链接至目标"></a></dt>
<dd><p>返回一个与使用 <a class="reference internal" href="#c.Py_tss_NEEDS_INIT" title="Py_tss_NEEDS_INIT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_tss_NEEDS_INIT</span></code></a> 初始化的值的状态相同的值,或者当动态分配失败时则返回 <code class="docutils literal notranslate"><span class="pre">NULL</span></code></p>
</dd></dl>
<dl class="function">
<dt id="c.PyThread_tss_free">
void <code class="sig-name descname">PyThread_tss_free</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_free" title="永久链接至目标"></a></dt>
<dd><p>Free the given <em>key</em> allocated by <a class="reference internal" href="#c.PyThread_tss_alloc" title="PyThread_tss_alloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_alloc()</span></code></a>, after
first calling <a class="reference internal" href="#c.PyThread_tss_delete" title="PyThread_tss_delete"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_delete()</span></code></a> to ensure any associated
thread locals have been unassigned. This is a no-op if the <em>key</em>
argument is <cite>NULL</cite>.</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>A freed key becomes a dangling pointer, you should reset the key to
<cite>NULL</cite>.</p>
</div>
</dd></dl>
</section>
<section id="methods">
<h4>方法<a class="headerlink" href="#methods" title="永久链接至标题"></a></h4>
<p>这些函数的形参 <em>key</em> 不可为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>。 并且,如果给定的 <a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tss_t</span></code></a> 还未被 <a class="reference internal" href="#c.PyThread_tss_create" title="PyThread_tss_create"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_create()</span></code></a> 初始化则 <a class="reference internal" href="#c.PyThread_tss_set" title="PyThread_tss_set"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_set()</span></code></a><a class="reference internal" href="#c.PyThread_tss_get" title="PyThread_tss_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_get()</span></code></a> 的行为将是未定义的。</p>
<dl class="function">
<dt id="c.PyThread_tss_is_created">
int <code class="sig-name descname">PyThread_tss_is_created</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_is_created" title="永久链接至目标"></a></dt>
<dd><p>如果给定的 <a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_tss_t</span></code></a> 已通过has been initialized by <a class="reference internal" href="#c.PyThread_tss_create" title="PyThread_tss_create"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_create()</span></code></a> 被初始化则返回一个非零值。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThread_tss_create">
int <code class="sig-name descname">PyThread_tss_create</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_create" title="永久链接至目标"></a></dt>
<dd><p>当成功初始化一个 TSS 键时将返回零值。 如果 <em>key</em> 参数所指向的值未被 <a class="reference internal" href="#c.Py_tss_NEEDS_INIT" title="Py_tss_NEEDS_INIT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_tss_NEEDS_INIT</span></code></a> 初始化则其行为是未定义的。 此函数可在相同的键上重复调用 -- 在已初始化的键上调用它将不执行任何操作并立即成功返回。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThread_tss_delete">
void <code class="sig-name descname">PyThread_tss_delete</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_delete" title="永久链接至目标"></a></dt>
<dd><p>销毁一个 TSS 键以便在所有线程中遗忘与该键相关联的值,并将该键的初始化状态改为未初始化的。 已销毁的键可以通过 <a class="reference internal" href="#c.PyThread_tss_create" title="PyThread_tss_create"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_tss_create()</span></code></a> 再次被初始化。 此函数可以在同一个键上重复调用 -- 但在一个已被销毁的键上调用将是无效的。</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThread_tss_set">
int <code class="sig-name descname">PyThread_tss_set</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em>, void<em> *value</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_set" title="永久链接至目标"></a></dt>
<dd><p>Return a zero value to indicate successfully associating a <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code>
value with a TSS key in the current thread. Each thread has a distinct
mapping of the key to a <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> value.</p>
</dd></dl>
<dl class="function">
<dt id="c.PyThread_tss_get">
void* <code class="sig-name descname">PyThread_tss_get</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_tss_t" title="Py_tss_t">Py_tss_t</a><em> *key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_tss_get" title="永久链接至目标"></a></dt>
<dd><p>Return the <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> value associated with a TSS key in the current
thread. This returns <code class="docutils literal notranslate"><span class="pre">NULL</span></code> if no value is associated with the key in the
current thread.</p>
</dd></dl>
</section>
</section>
<section id="thread-local-storage-tls-api">
<span id="thread-local-storage-api"></span><h3>线程本地存储 (TLS) API<a class="headerlink" href="#thread-local-storage-tls-api" title="永久链接至标题"></a></h3>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>此 API 已被 <a class="reference internal" href="#thread-specific-storage-api"><span class="std std-ref">线程专属存储 (TSS) API</span></a> 所取代。</p>
</div>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>这个 API 版本不支持原生 TLS 键采用无法被安全转换为 <code class="docutils literal notranslate"><span class="pre">int</span></code> 的的定义方式的平台。 在这样的平台上,<a class="reference internal" href="#c.PyThread_create_key" title="PyThread_create_key"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_create_key()</span></code></a> 将立即返回一个失败状态,并且其他 TLS 函数在这样的平台上也都无效。</p>
</div>
<p>由于上面提到的兼容性问题不应在新代码中使用此版本的API。</p>
<dl class="function">
<dt id="c.PyThread_create_key">
int <code class="sig-name descname">PyThread_create_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_create_key" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="c.PyThread_delete_key">
void <code class="sig-name descname">PyThread_delete_key</code><span class="sig-paren">(</span>int<em> key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_delete_key" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="c.PyThread_set_key_value">
int <code class="sig-name descname">PyThread_set_key_value</code><span class="sig-paren">(</span>int<em> key</em>, void<em> *value</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_set_key_value" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="c.PyThread_get_key_value">
void* <code class="sig-name descname">PyThread_get_key_value</code><span class="sig-paren">(</span>int<em> key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_get_key_value" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="c.PyThread_delete_key_value">
void <code class="sig-name descname">PyThread_delete_key_value</code><span class="sig-paren">(</span>int<em> key</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_delete_key_value" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="c.PyThread_ReInitTLS">
void <code class="sig-name descname">PyThread_ReInitTLS</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_ReInitTLS" title="永久链接至目标"></a></dt>
<dd></dd></dl>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">初始化,最终化和线程</a><ul>
<li><a class="reference internal" href="#before-python-initialization">在Python初始化之前</a></li>
<li><a class="reference internal" href="#global-configuration-variables">全局配置变量</a></li>
<li><a class="reference internal" href="#initializing-and-finalizing-the-interpreter">初始化和最终化解释器</a></li>
<li><a class="reference internal" href="#process-wide-parameters">进程级参数</a></li>
<li><a class="reference internal" href="#thread-state-and-the-global-interpreter-lock">线程状态和全局解释器锁</a><ul>
<li><a class="reference internal" href="#releasing-the-gil-from-extension-code">从扩展扩展代码中释放 GIL</a></li>
<li><a class="reference internal" href="#non-python-created-threads">非Python创建的线程</a></li>
<li><a class="reference internal" href="#cautions-about-fork">有关 fork() 的注意事项</a></li>
<li><a class="reference internal" href="#high-level-api">高阶 API</a></li>
<li><a class="reference internal" href="#low-level-api">底层级 API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#sub-interpreter-support">子解释器支持</a><ul>
<li><a class="reference internal" href="#bugs-and-caveats">错误和警告</a></li>
</ul>
</li>
<li><a class="reference internal" href="#asynchronous-notifications">异步通知</a></li>
<li><a class="reference internal" href="#profiling-and-tracing">分析和跟踪</a></li>
<li><a class="reference internal" href="#advanced-debugger-support">高级调试器支持</a></li>
<li><a class="reference internal" href="#thread-local-storage-support">线程本地存储支持</a><ul>
<li><a class="reference internal" href="#thread-specific-storage-tss-api">线程专属存储 (TSS) API</a><ul>
<li><a class="reference internal" href="#dynamic-allocation">动态分配</a></li>
<li><a class="reference internal" href="#methods">方法</a></li>
</ul>
</li>
<li><a class="reference internal" href="#thread-local-storage-tls-api">线程本地存储 (TLS) API</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="datetime.html"
title="上一章">DateTime 对象</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="init_config.html"
title="下一章">Python初始化配置</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/c-api/init.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="init_config.html" title="Python初始化配置"
>下一页</a> |</li>
<li class="right" >
<a href="datetime.html" title="DateTime 对象"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python/C API 参考手册</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>