834 lines
70 KiB
HTML
834 lines
70 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="../">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta property="og:title" content="Multiple interpreters in a Python process" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:url" content="https://docs.python.org/3/c-api/subinterpreters.html" />
|
||
<meta property="og:site_name" content="Python documentation" />
|
||
<meta property="og:description" content="While in most uses, you will only embed a single Python interpreter, there are cases where you need to create several independent interpreters in the same process and perhaps even in the same threa..." />
|
||
<meta property="og:image" content="_static/og-image.png" />
|
||
<meta property="og:image:alt" content="Python documentation" />
|
||
<meta name="description" content="While in most uses, you will only embed a single Python interpreter, there are cases where you need to create several independent interpreters in the same process and perhaps even in the same threa..." />
|
||
<meta name="theme-color" content="#3776ab">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
|
||
<title>Multiple interpreters in a Python process — Python 3.15.0 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/classic.css?v=234b1a7c" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=48df1187" />
|
||
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=0fc419ee" />
|
||
|
||
<script src="../_static/documentation_options.js?v=0fe728b1"></script>
|
||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.15.0 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="Profiling and tracing" href="profiling.html" />
|
||
<link rel="prev" title="Thread-local storage support" href="tls.html" />
|
||
|
||
|
||
<link rel="canonical" href="https://docs.python.org/3/c-api/subinterpreters.html">
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
|
||
<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>
|
||
<script type="text/javascript" src="../_static/search-focus.js"></script>
|
||
<script type="text/javascript" src="../_static/themetoggle.js"></script>
|
||
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
|
||
<meta name="readthedocs-addons-api-version" content="1">
|
||
|
||
</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">
|
||
<nav class="nav-content" role="navigation">
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<span class="nav-items-wrapper">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Python logo">
|
||
</a>
|
||
<span class="version_switcher_placeholder"></span>
|
||
<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" fill="currentColor" 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"></path>
|
||
</svg>
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q">
|
||
<input type="submit" value="Go">
|
||
</form>
|
||
</span>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label>
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Multiple interpreters in a Python process</a><ul>
|
||
<li><a class="reference internal" href="#a-per-interpreter-gil">A per-interpreter GIL</a></li>
|
||
<li><a class="reference internal" href="#bugs-and-caveats">Bugs and caveats</a></li>
|
||
<li><a class="reference internal" href="#high-level-apis">High-level APIs</a></li>
|
||
<li><a class="reference internal" href="#low-level-apis">Low-level APIs</a></li>
|
||
<li><a class="reference internal" href="#advanced-debugger-support">Advanced debugger support</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="tls.html"
|
||
title="previous chapter">Thread-local storage support</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="profiling.html"
|
||
title="next chapter">Profiling and tracing</a></p>
|
||
</div>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const title = document.querySelector('meta[property="og:title"]').content;
|
||
const elements = document.querySelectorAll('.improvepage');
|
||
const pageurl = window.location.href.split('?')[0];
|
||
elements.forEach(element => {
|
||
const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
|
||
url.searchParams.set('pagetitle', title);
|
||
url.searchParams.set('pageurl', pageurl);
|
||
url.searchParams.set('pagesource', "c-api/subinterpreters.rst");
|
||
element.href = url.toString();
|
||
});
|
||
});
|
||
</script>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a bug</a></li>
|
||
<li><a class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.15/Doc/c-api/subinterpreters.rst?plain=1"
|
||
rel="nofollow">Show source
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="profiling.html" title="Profiling and tracing"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="tls.html" title="Thread-local storage support"
|
||
accesskey="P">previous</a> |</li>
|
||
|
||
<li class="root-icon"><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> »</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.15.0 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python/C API reference manual</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Multiple interpreters in a Python process</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box">
|
||
<input type="submit" value="Go">
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="multiple-interpreters-in-a-python-process">
|
||
<span id="sub-interpreter-support"></span><h1>Multiple interpreters in a Python process<a class="headerlink" href="#multiple-interpreters-in-a-python-process" title="Link to this heading">¶</a></h1>
|
||
<p>While in most uses, you will only embed a single Python interpreter, there
|
||
are cases where you need to create several independent interpreters in the
|
||
same process and perhaps even in the same thread. Sub-interpreters allow
|
||
you to do that.</p>
|
||
<p>The “main” interpreter is the first one created when the runtime initializes.
|
||
It is usually the only Python interpreter in a process. Unlike sub-interpreters,
|
||
the main interpreter has unique process-global responsibilities like signal
|
||
handling. It is also responsible for execution during runtime initialization and
|
||
is usually the active interpreter during runtime finalization. The
|
||
<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> function returns a pointer to its state.</p>
|
||
<p>You can switch between sub-interpreters using the <a class="reference internal" href="threads.html#c.PyThreadState_Swap" title="PyThreadState_Swap"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThreadState_Swap()</span></code></a>
|
||
function. You can create and destroy them using the following functions:</p>
|
||
<dl class="c type">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig">
|
||
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterConfig</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Structure containing most parameters to configure a sub-interpreter.
|
||
Its values are used only in <a class="reference internal" href="#c.Py_NewInterpreterFromConfig" title="Py_NewInterpreterFromConfig"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreterFromConfig()</span></code></a> and
|
||
never modified by the runtime.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.12.</span></p>
|
||
</div>
|
||
<p>Structure fields:</p>
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.use_main_obmalloc">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">use_main_obmalloc</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.use_main_obmalloc" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then the sub-interpreter will use its own
|
||
“object” allocator state.
|
||
Otherwise it will use (share) the main interpreter’s.</p>
|
||
<p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then
|
||
<a class="reference internal" href="#c.PyInterpreterConfig.check_multi_interp_extensions" title="PyInterpreterConfig.check_multi_interp_extensions"><code class="xref c c-member docutils literal notranslate"><span class="pre">check_multi_interp_extensions</span></code></a>
|
||
must be <code class="docutils literal notranslate"><span class="pre">1</span></code> (non-zero).
|
||
If this is <code class="docutils literal notranslate"><span class="pre">1</span></code> then <a class="reference internal" href="#c.PyInterpreterConfig.gil" title="PyInterpreterConfig.gil"><code class="xref c c-member docutils literal notranslate"><span class="pre">gil</span></code></a>
|
||
must not be <a class="reference internal" href="#c.PyInterpreterConfig_OWN_GIL" title="PyInterpreterConfig_OWN_GIL"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyInterpreterConfig_OWN_GIL</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.allow_fork">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">allow_fork</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.allow_fork" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then the runtime will not support forking the
|
||
process in any thread where the sub-interpreter is currently active.
|
||
Otherwise fork is unrestricted.</p>
|
||
<p>Note that the <a class="reference internal" href="../library/subprocess.html#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal notranslate"><span class="pre">subprocess</span></code></a> module still works
|
||
when fork is disallowed.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.allow_exec">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">allow_exec</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.allow_exec" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then the runtime will not support replacing the
|
||
current process via exec (e.g. <a class="reference internal" href="../library/os.html#os.execv" title="os.execv"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.execv()</span></code></a>) in any thread
|
||
where the sub-interpreter is currently active.
|
||
Otherwise exec is unrestricted.</p>
|
||
<p>Note that the <a class="reference internal" href="../library/subprocess.html#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal notranslate"><span class="pre">subprocess</span></code></a> module still works
|
||
when exec is disallowed.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.allow_threads">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">allow_threads</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.allow_threads" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then the sub-interpreter’s <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> module
|
||
won’t create threads.
|
||
Otherwise threads are allowed.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.allow_daemon_threads">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">allow_daemon_threads</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.allow_daemon_threads" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then the sub-interpreter’s <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> module
|
||
won’t create daemon threads.
|
||
Otherwise daemon threads are allowed (as long as
|
||
<a class="reference internal" href="#c.PyInterpreterConfig.allow_threads" title="PyInterpreterConfig.allow_threads"><code class="xref c c-member docutils literal notranslate"><span class="pre">allow_threads</span></code></a> is non-zero).</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.check_multi_interp_extensions">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">check_multi_interp_extensions</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.check_multi_interp_extensions" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>If this is <code class="docutils literal notranslate"><span class="pre">0</span></code> then all extension modules may be imported,
|
||
including legacy (single-phase init) modules,
|
||
in any thread where the sub-interpreter is currently active.
|
||
Otherwise only multi-phase init extension modules
|
||
(see <span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0489/"><strong>PEP 489</strong></a>) may be imported.
|
||
(Also see <a class="reference internal" href="module.html#c.Py_mod_multiple_interpreters" title="Py_mod_multiple_interpreters"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_mod_multiple_interpreters</span></code></a>.)</p>
|
||
<p>This must be <code class="docutils literal notranslate"><span class="pre">1</span></code> (non-zero) if
|
||
<a class="reference internal" href="#c.PyInterpreterConfig.use_main_obmalloc" title="PyInterpreterConfig.use_main_obmalloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">use_main_obmalloc</span></code></a> is <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c member">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig.gil">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">gil</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig.gil" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>This determines the operation of the GIL for the sub-interpreter.
|
||
It may be one of the following:</p>
|
||
<dl class="c macro">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig_DEFAULT_GIL">
|
||
<span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterConfig_DEFAULT_GIL</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig_DEFAULT_GIL" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Use the default selection (<a class="reference internal" href="#c.PyInterpreterConfig_SHARED_GIL" title="PyInterpreterConfig_SHARED_GIL"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyInterpreterConfig_SHARED_GIL</span></code></a>).</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c macro">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig_SHARED_GIL">
|
||
<span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterConfig_SHARED_GIL</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig_SHARED_GIL" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Use (share) the main interpreter’s GIL.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c macro">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterConfig_OWN_GIL">
|
||
<span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterConfig_OWN_GIL</span></span></span><a class="headerlink" href="#c.PyInterpreterConfig_OWN_GIL" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Use the sub-interpreter’s own GIL.</p>
|
||
</dd></dl>
|
||
|
||
<p>If this is <a class="reference internal" href="#c.PyInterpreterConfig_OWN_GIL" title="PyInterpreterConfig_OWN_GIL"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyInterpreterConfig_OWN_GIL</span></code></a> then
|
||
<a class="reference internal" href="#c.PyInterpreterConfig.use_main_obmalloc" title="PyInterpreterConfig.use_main_obmalloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">PyInterpreterConfig.use_main_obmalloc</span></code></a> must be <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.Py_NewInterpreterFromConfig">
|
||
<a class="reference internal" href="init_config.html#c.PyStatus" title="PyStatus"><span class="n"><span class="pre">PyStatus</span></span></a><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">Py_NewInterpreterFromConfig</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">tstate_p</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><a class="reference internal" href="#c.PyInterpreterConfig" title="PyInterpreterConfig"><span class="n"><span class="pre">PyInterpreterConfig</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">config</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_NewInterpreterFromConfig" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p id="index-1">Create a new sub-interpreter. This is an (almost) totally separate environment
|
||
for the execution of Python code. In particular, the new interpreter has
|
||
separate, independent versions of all imported modules, including the
|
||
fundamental modules <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 top-level code is run. Covers command-line interfaces, import-time behavior, and ``__name__ == '__main__'``."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> and <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>. The
|
||
table of loaded modules (<code class="docutils literal notranslate"><span class="pre">sys.modules</span></code>) and the module search path
|
||
(<code class="docutils literal notranslate"><span class="pre">sys.path</span></code>) are also separate. The new environment has no <code class="docutils literal notranslate"><span class="pre">sys.argv</span></code>
|
||
variable. It has new standard I/O stream file objects <code class="docutils literal notranslate"><span class="pre">sys.stdin</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">sys.stdout</span></code> and <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code> (however these refer to the same underlying
|
||
file descriptors).</p>
|
||
<p>The given <em>config</em> controls the options with which the interpreter
|
||
is initialized.</p>
|
||
<p>Upon success, <em>tstate_p</em> will be set to the first <a class="reference internal" href="../glossary.html#term-thread-state"><span class="xref std std-term">thread state</span></a>
|
||
created in the new sub-interpreter. This thread state is
|
||
<a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached</span></a>.
|
||
Note that no actual thread is created; see the discussion of thread states
|
||
below. If creation of the new interpreter is unsuccessful,
|
||
<em>tstate_p</em> is set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code>;
|
||
no exception is set since the exception state is stored in the
|
||
<span class="xref std std-term">attached thread state</span>, which might not exist.</p>
|
||
<p>Like all other Python/C API functions, an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>
|
||
must be present before calling this function, but it might be detached upon
|
||
returning. On success, the returned thread state will be <span class="xref std std-term">attached</span>.
|
||
If the sub-interpreter is created with its own <a class="reference internal" href="../glossary.html#term-GIL"><span class="xref std std-term">GIL</span></a> then the
|
||
<span class="xref std std-term">attached thread state</span> of the calling interpreter will be detached.
|
||
When the function returns, the new interpreter’s <a class="reference internal" href="../glossary.html#term-thread-state"><span class="xref std std-term">thread state</span></a>
|
||
will be <span class="xref std std-term">attached</span> to the current thread and
|
||
the previous interpreter’s <span class="xref std std-term">attached thread state</span> will remain detached.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.12.</span></p>
|
||
</div>
|
||
<p>Sub-interpreters are most effective when isolated from each other,
|
||
with certain functionality restricted:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyInterpreterConfig</span><span class="w"> </span><span class="n">config</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">use_main_obmalloc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">allow_fork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">allow_exec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">allow_threads</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">allow_daemon_threads</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">check_multi_interp_extensions</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="p">.</span><span class="n">gil</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyInterpreterConfig_OWN_GIL</span><span class="p">,</span>
|
||
<span class="p">};</span>
|
||
<span class="n">PyThreadState</span><span class="w"> </span><span class="o">*</span><span class="n">tstate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="n">PyStatus</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_NewInterpreterFromConfig</span><span class="p">(</span><span class="o">&</span><span class="n">tstate</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">config</span><span class="p">);</span>
|
||
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyStatus_Exception</span><span class="p">(</span><span class="n">status</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Py_ExitStatusException</span><span class="p">(</span><span class="n">status</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that the config is used only briefly and does not get modified.
|
||
During initialization the config’s values are converted into various
|
||
<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> values. A read-only copy of the config
|
||
may be stored internally on the <code class="xref c c-type docutils literal notranslate"><span class="pre">PyInterpreterState</span></code>.</p>
|
||
<p id="index-2">Extension modules are shared between (sub-)interpreters as follows:</p>
|
||
<ul>
|
||
<li><p>For modules using multi-phase initialization,
|
||
e.g. <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>, a separate module object is
|
||
created and initialized for each interpreter.
|
||
Only C-level static and global variables are shared between these
|
||
module objects.</p></li>
|
||
<li><p>For modules using legacy
|
||
<a class="reference internal" href="extension-modules.html#single-phase-initialization"><span class="std std-ref">single-phase initialization</span></a>,
|
||
e.g. <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>, the first time a particular extension
|
||
is imported, it is initialized normally, and a (shallow) copy of its
|
||
module’s dictionary is squirreled away.
|
||
When the same extension is imported by another (sub-)interpreter, a new
|
||
module is initialized and filled with the contents of this copy; the
|
||
extension’s <code class="docutils literal notranslate"><span class="pre">init</span></code> function is not called.
|
||
Objects in the module’s dictionary thus end up shared across
|
||
(sub-)interpreters, which might cause unwanted behavior (see
|
||
<a class="reference internal" href="#bugs-and-caveats">Bugs and caveats</a> below).</p>
|
||
<p>Note that this is different from what happens when an extension is
|
||
imported after the interpreter has been completely re-initialized by
|
||
calling <a class="reference internal" href="interp-lifecycle.html#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> and <a class="reference internal" href="interp-lifecycle.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>; in that
|
||
case, the extension’s <code class="docutils literal notranslate"><span class="pre">initmodule</span></code> function <em>is</em> called again.
|
||
As with multi-phase initialization, this means that only C-level static
|
||
and global variables are shared between these modules.</p>
|
||
</li>
|
||
</ul>
|
||
<span class="target" id="index-3"></span></dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.Py_NewInterpreter">
|
||
<a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">Py_NewInterpreter</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">void</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_NewInterpreter" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a>.</em><p id="index-4">Create a new sub-interpreter. This is essentially just a wrapper
|
||
around <a class="reference internal" href="#c.Py_NewInterpreterFromConfig" title="Py_NewInterpreterFromConfig"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreterFromConfig()</span></code></a> with a config that
|
||
preserves the existing behavior. The result is an unisolated
|
||
sub-interpreter that shares the main interpreter’s GIL, allows
|
||
fork/exec, allows daemon threads, and allows single-phase init
|
||
modules.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.Py_EndInterpreter">
|
||
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">Py_EndInterpreter</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">tstate</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_EndInterpreter" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a>.</em><p id="index-5">Destroy the (sub-)interpreter represented by the given <a class="reference internal" href="../glossary.html#term-thread-state"><span class="xref std std-term">thread state</span></a>.
|
||
The given thread state must be <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached</span></a>.
|
||
When the call returns, there will be no <span class="xref std std-term">attached thread state</span>.
|
||
All thread states associated with this interpreter are destroyed.</p>
|
||
<p><a class="reference internal" href="interp-lifecycle.html#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="a-per-interpreter-gil">
|
||
<span id="per-interpreter-gil"></span><h2>A per-interpreter GIL<a class="headerlink" href="#a-per-interpreter-gil" title="Link to this heading">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.12.</span></p>
|
||
</div>
|
||
<p>Using <a class="reference internal" href="#c.Py_NewInterpreterFromConfig" title="Py_NewInterpreterFromConfig"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreterFromConfig()</span></code></a> you can create
|
||
a sub-interpreter that is completely isolated from other interpreters,
|
||
including having its own GIL. The most important benefit of this
|
||
isolation is that such an interpreter can execute Python code without
|
||
being blocked by other interpreters or blocking any others. Thus a
|
||
single Python process can truly take advantage of multiple CPU cores
|
||
when running Python code. The isolation also encourages a different
|
||
approach to concurrency than that of just using threads.
|
||
(See <span class="target" id="index-6"></span><a class="pep reference external" href="https://peps.python.org/pep-0554/"><strong>PEP 554</strong></a> and <span class="target" id="index-7"></span><a class="pep reference external" href="https://peps.python.org/pep-0684/"><strong>PEP 684</strong></a>.)</p>
|
||
<p>Using an isolated interpreter requires vigilance in preserving that
|
||
isolation. That especially means not sharing any objects or mutable
|
||
state without guarantees about thread-safety. Even objects that are
|
||
otherwise immutable (e.g. <code class="docutils literal notranslate"><span class="pre">None</span></code>, <code class="docutils literal notranslate"><span class="pre">(1,</span> <span class="pre">5)</span></code>) can’t normally be shared
|
||
because of the refcount. One simple but less-efficient approach around
|
||
this is to use a global lock around all use of some state (or object).
|
||
Alternately, effectively immutable objects (like integers or strings)
|
||
can be made safe in spite of their refcounts by making them <a class="reference internal" href="../glossary.html#term-immortal"><span class="xref std std-term">immortal</span></a>.
|
||
In fact, this has been done for the builtin singletons, small integers,
|
||
and a number of other builtin objects.</p>
|
||
<p>If you preserve isolation then you will have access to proper multi-core
|
||
computing without the complications that come with free-threading.
|
||
Failure to preserve isolation will expose you to the full consequences
|
||
of free-threading, including races and hard-to-debug crashes.</p>
|
||
<p>Aside from that, one of the main challenges of using multiple isolated
|
||
interpreters is how to communicate between them safely (not break
|
||
isolation) and efficiently. The runtime and stdlib do not provide
|
||
any standard approach to this yet. A future stdlib module would help
|
||
mitigate the effort of preserving isolation and expose effective tools
|
||
for communicating (and sharing) data between interpreters.</p>
|
||
</section>
|
||
<section id="bugs-and-caveats">
|
||
<h2>Bugs and caveats<a class="headerlink" href="#bugs-and-caveats" title="Link to this heading">¶</a></h2>
|
||
<p>Because sub-interpreters (and the main interpreter) are part of the same
|
||
process, the insulation between them isn’t perfect — for example, using
|
||
low-level file operations like <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> they can
|
||
(accidentally or maliciously) affect each other’s open files. Because of the
|
||
way extensions are shared between (sub-)interpreters, some extensions may not
|
||
work properly; this is especially likely when using single-phase initialization
|
||
or (static) global variables.
|
||
It is possible to insert objects created in one sub-interpreter into
|
||
a namespace of another (sub-)interpreter; this should be avoided if possible.</p>
|
||
<p>Special care should be taken to avoid sharing user-defined functions,
|
||
methods, instances or classes between sub-interpreters, since import
|
||
operations executed by such objects may affect the wrong (sub-)interpreter’s
|
||
dictionary of loaded modules. It is equally important to avoid sharing
|
||
objects from which the above are reachable.</p>
|
||
<p>Also note that combining this functionality with <code class="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="threads.html#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="threads.html#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 id="high-level-apis">
|
||
<h2>High-level APIs<a class="headerlink" href="#high-level-apis" title="Link to this heading">¶</a></h2>
|
||
<dl class="c type">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState">
|
||
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState</span></span></span><a class="headerlink" href="#c.PyInterpreterState" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a> (as an opaque struct).</em><p>This data structure represents the state shared by a number of cooperating
|
||
threads. Threads belonging to the same interpreter share their module
|
||
administration and a few other internal items. There are no public members in
|
||
this structure.</p>
|
||
<p>Threads belonging to different interpreters initially share nothing, except
|
||
process state like available memory, open file descriptors and such. The global
|
||
interpreter lock is also shared by all threads, regardless of to which
|
||
interpreter they belong.</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.12: </span><span class="target" id="index-8"></span><a class="pep reference external" href="https://peps.python.org/pep-0684/"><strong>PEP 684</strong></a> introduced the possibility
|
||
of a <a class="reference internal" href="#per-interpreter-gil"><span class="std std-ref">per-interpreter GIL</span></a>.
|
||
See <a class="reference internal" href="#c.Py_NewInterpreterFromConfig" title="Py_NewInterpreterFromConfig"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_NewInterpreterFromConfig()</span></code></a>.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Get">
|
||
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Get</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">void</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Get" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a> since version 3.9.</em><p>Get the current interpreter.</p>
|
||
<p>Issue a fatal error if there is no <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.
|
||
It cannot return NULL.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.9.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_GetID">
|
||
<span class="n"><span class="pre">int64_t</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_GetID</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_GetID" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a> since version 3.7.</em><p>Return the interpreter’s unique ID. If there was any error in doing
|
||
so then <code class="docutils literal notranslate"><span class="pre">-1</span></code> is returned and an error is set.</p>
|
||
<p>The caller must have an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.7.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_GetDict">
|
||
<a class="reference internal" href="structures.html#c.PyObject" title="PyObject"><span class="n"><span class="pre">PyObject</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_GetDict</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_GetDict" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="refcount return_borrowed_ref">Return value: Borrowed reference.</em><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a> since version 3.8.</em><p>Return a dictionary in which interpreter-specific data may be stored.
|
||
If this function returns <code class="docutils literal notranslate"><span class="pre">NULL</span></code> then no exception has been raised and
|
||
the caller should assume no interpreter-specific dict is available.</p>
|
||
<p>This is not a replacement for <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>, which
|
||
extensions should use to store interpreter-specific state information.</p>
|
||
<p>The returned dictionary is borrowed from the interpreter and is valid until
|
||
interpreter shutdown.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.8.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c type">
|
||
<dt class="sig sig-object c" id="c._PyFrameEvalFunction">
|
||
<span class="k"><span class="pre">typedef</span></span><span class="w"> </span><a class="reference internal" href="structures.html#c.PyObject" title="PyObject"><span class="n"><span class="pre">PyObject</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">(</span></span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">_PyFrameEvalFunction</span></span></span><span class="p"><span class="pre">)</span></span><span class="p"><span class="pre">(</span></span><a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">tstate</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="frame.html#c._PyInterpreterFrame" title="_PyInterpreterFrame"><span class="n"><span class="pre">_PyInterpreterFrame</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">frame</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">throwflag</span></span><span class="p"><span class="pre">)</span></span><a class="headerlink" href="#c._PyFrameEvalFunction" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Type of a frame evaluation function.</p>
|
||
<p>The <em>throwflag</em> parameter is used by the <code class="docutils literal notranslate"><span class="pre">throw()</span></code> method of generators:
|
||
if non-zero, handle the current exception.</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.9: </span>The function now takes a <em>tstate</em> parameter.</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.11: </span>The <em>frame</em> parameter changed from <code class="docutils literal notranslate"><span class="pre">PyFrameObject*</span></code> to <code class="docutils literal notranslate"><span class="pre">_PyInterpreterFrame*</span></code>.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c._PyInterpreterState_GetEvalFrameFunc">
|
||
<a class="reference internal" href="#c._PyFrameEvalFunction" title="_PyFrameEvalFunction"><span class="n"><span class="pre">_PyFrameEvalFunction</span></span></a><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">_PyInterpreterState_GetEvalFrameFunc</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c._PyInterpreterState_GetEvalFrameFunc" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Get the frame evaluation function.</p>
|
||
<p>See the <span class="target" id="index-9"></span><a class="pep reference external" href="https://peps.python.org/pep-0523/"><strong>PEP 523</strong></a> “Adding a frame evaluation API to CPython”.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.9.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c._PyInterpreterState_SetEvalFrameFunc">
|
||
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">_PyInterpreterState_SetEvalFrameFunc</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span>, <a class="reference internal" href="#c._PyFrameEvalFunction" title="_PyFrameEvalFunction"><span class="n"><span class="pre">_PyFrameEvalFunction</span></span></a><span class="w"> </span><span class="n"><span class="pre">eval_frame</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c._PyInterpreterState_SetEvalFrameFunc" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Set the frame evaluation function.</p>
|
||
<p>See the <span class="target" id="index-10"></span><a class="pep reference external" href="https://peps.python.org/pep-0523/"><strong>PEP 523</strong></a> “Adding a frame evaluation API to CPython”.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.9.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c._PyInterpreterState_SetEvalFrameAllowSpecialization">
|
||
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">_PyInterpreterState_SetEvalFrameAllowSpecialization</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">allow_specialization</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c._PyInterpreterState_SetEvalFrameAllowSpecialization" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Enables or disables specialization why a custom frame evaluator is in place.</p>
|
||
<p>If <em>allow_specialization</em> is non-zero, the adaptive specializer will
|
||
continue to specialize bytecodes even though a custom eval frame function
|
||
is set. When <em>allow_specialization</em> is zero, setting a custom eval frame
|
||
disables specialization. The standard interpreter loop will continue to deopt
|
||
while a frame evaluation API is in place - the frame evaluation function needs
|
||
to handle the specialized opcodes to take advantage of this.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.15.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c._PyInterpreterState_IsSpecializationEnabled">
|
||
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">_PyInterpreterState_IsSpecializationEnabled</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c._PyInterpreterState_IsSpecializationEnabled" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return non-zero if adaptive specialization is enabled for the interpreter.
|
||
Specialization is enabled when no custom eval frame function is set, or
|
||
when one is set with <em>allow_specialization</em> enabled.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.15.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="low-level-apis">
|
||
<h2>Low-level APIs<a class="headerlink" href="#low-level-apis" title="Link to this heading">¶</a></h2>
|
||
<p>All of the following functions must be called after <a class="reference internal" href="interp-lifecycle.html#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">Changed in version 3.7: </span><a class="reference internal" href="interp-lifecycle.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> now initializes the <a class="reference internal" href="../glossary.html#term-GIL"><span class="xref std std-term">GIL</span></a>
|
||
and sets an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</p>
|
||
</div>
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_New">
|
||
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_New</span></span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_New" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a>.</em><p>Create a new interpreter state object. An <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a> is not needed,
|
||
but may optionally exist if it is necessary to serialize calls to this
|
||
function.</p>
|
||
<p class="audit-hook">Raises an <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">auditing event</span></a> <code class="docutils literal notranslate"><span class="pre">cpython.PyInterpreterState_New</span></code> with no arguments.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Clear">
|
||
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Clear</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Clear" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a>.</em><p>Reset all information in an interpreter state object. There must be
|
||
an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a> for the interpreter.</p>
|
||
<p class="audit-hook">Raises an <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">auditing event</span></a> <code class="docutils literal notranslate"><span class="pre">cpython.PyInterpreterState_Clear</span></code> with no arguments.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Delete">
|
||
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Delete</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Delete" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><em class="stableabi"> Part of the <a class="reference internal" href="stable.html#stable"><span class="std std-ref">Stable ABI</span></a>.</em><p>Destroy an interpreter state object. There <strong>should not</strong> be an
|
||
<a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a> for the target interpreter. The interpreter
|
||
state must have been reset with a previous call to <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>
|
||
|
||
</section>
|
||
<section id="advanced-debugger-support">
|
||
<span id="advanced-debugging"></span><h2>Advanced debugger support<a class="headerlink" href="#advanced-debugger-support" title="Link to this heading">¶</a></h2>
|
||
<p>These functions are only intended to be used by advanced debugging tools.</p>
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Head">
|
||
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Head</span></span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Head" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return the interpreter state object at the head of the list of all such objects.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Main">
|
||
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Main</span></span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Main" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return the main interpreter state object.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_Next">
|
||
<a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_Next</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_Next" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return the next interpreter state object after <em>interp</em> from the list of all
|
||
such objects.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyInterpreterState_ThreadHead">
|
||
<a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInterpreterState_ThreadHead</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyInterpreterState" title="PyInterpreterState"><span class="n"><span class="pre">PyInterpreterState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">interp</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInterpreterState_ThreadHead" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return the pointer to the first <a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyThreadState</span></code></a> object in the list of
|
||
threads associated with the interpreter <em>interp</em>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="c function">
|
||
<dt class="sig sig-object c" id="c.PyThreadState_Next">
|
||
<a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyThreadState_Next</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="threads.html#c.PyThreadState" title="PyThreadState"><span class="n"><span class="pre">PyThreadState</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">tstate</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThreadState_Next" title="Link to this definition">¶</a><br /></dt>
|
||
<dd><p>Return the next thread state object after <em>tstate</em> from the list of all such
|
||
objects belonging to the same <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> object.</p>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
||
<div class="sphinxsidebarwrapper">
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Multiple interpreters in a Python process</a><ul>
|
||
<li><a class="reference internal" href="#a-per-interpreter-gil">A per-interpreter GIL</a></li>
|
||
<li><a class="reference internal" href="#bugs-and-caveats">Bugs and caveats</a></li>
|
||
<li><a class="reference internal" href="#high-level-apis">High-level APIs</a></li>
|
||
<li><a class="reference internal" href="#low-level-apis">Low-level APIs</a></li>
|
||
<li><a class="reference internal" href="#advanced-debugger-support">Advanced debugger support</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="tls.html"
|
||
title="previous chapter">Thread-local storage support</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="profiling.html"
|
||
title="next chapter">Profiling and tracing</a></p>
|
||
</div>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const title = document.querySelector('meta[property="og:title"]').content;
|
||
const elements = document.querySelectorAll('.improvepage');
|
||
const pageurl = window.location.href.split('?')[0];
|
||
elements.forEach(element => {
|
||
const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
|
||
url.searchParams.set('pagetitle', title);
|
||
url.searchParams.set('pageurl', pageurl);
|
||
url.searchParams.set('pagesource', "c-api/subinterpreters.rst");
|
||
element.href = url.toString();
|
||
});
|
||
});
|
||
</script>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a bug</a></li>
|
||
<li><a class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.15/Doc/c-api/subinterpreters.rst?plain=1"
|
||
rel="nofollow">Show source
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="sidebarbutton" title="Collapse sidebar">
|
||
<span>«</span>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="profiling.html" title="Profiling and tracing"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="tls.html" title="Thread-local storage support"
|
||
>previous</a> |</li>
|
||
|
||
<li class="root-icon"><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> »</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.15.0 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python/C API reference manual</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Multiple interpreters in a Python process</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box">
|
||
<input type="submit" value="Go">
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">Copyright</a> 2001 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>
|
||
|
||
See <a href="/license.html">History and License</a> for more information.<br>
|
||
|
||
|
||
<br>
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br>
|
||
<br>
|
||
Last updated on Oct 09, 2026 (11:35 UTC).
|
||
|
||
<a href="/bugs.html">Found a bug</a>?
|
||
|
||
<br>
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |