Mini Kabibi Habibi

Current Path : C:/Users/ITO/AppData/Local/Programs/Python/Python314/Doc/html/howto/
Upload File :
Current File : C:/Users/ITO/AppData/Local/Programs/Python/Python314/Doc/html/howto/free-threading-extensions.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="C API Extension Support for Free Threading" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/howto/free-threading-extensions.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="Starting with the 3.13 release, CPython has support for running with the global interpreter lock(GIL) disabled in a configuration called free threading. This document describes how to adapt C API e..." />
<meta property="og:image" content="_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="Starting with the 3.13 release, CPython has support for running with the global interpreter lock(GIL) disabled in a configuration called free threading. This document describes how to adapt C API e..." />
<meta name="theme-color" content="#3776ab">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">

    <title>C API Extension Support for Free Threading &#8212; Python 3.14.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=8cd84f99" />
    <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
    
    <script src="../_static/documentation_options.js?v=e4f4b189"></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.14.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="Remote debugging attachment protocol" href="remote_debugging.html" />
    <link rel="prev" title="Python support for free threading" href="free-threading-python.html" />
    
      
      <link rel="canonical" href="https://docs.python.org/3/howto/free-threading-extensions.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="#">C API Extension Support for Free Threading</a><ul>
<li><a class="reference internal" href="#identifying-the-free-threaded-build-in-c">Identifying the Free-Threaded Build in C</a></li>
<li><a class="reference internal" href="#module-initialization">Module Initialization</a><ul>
<li><a class="reference internal" href="#multi-phase-initialization">Multi-Phase Initialization</a></li>
<li><a class="reference internal" href="#single-phase-initialization">Single-Phase Initialization</a></li>
</ul>
</li>
<li><a class="reference internal" href="#general-api-guidelines">General API Guidelines</a><ul>
<li><a class="reference internal" href="#container-thread-safety">Container Thread Safety</a><ul>
<li><a class="reference internal" href="#pydict-next"><code class="docutils literal notranslate"><span class="pre">PyDict_Next</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#borrowed-references">Borrowed References</a></li>
<li><a class="reference internal" href="#memory-allocation-apis">Memory Allocation APIs</a></li>
<li><a class="reference internal" href="#thread-state-and-gil-apis">Thread State and GIL APIs</a></li>
<li><a class="reference internal" href="#protecting-internal-extension-state">Protecting Internal Extension State</a></li>
<li><a class="reference internal" href="#critical-sections">Critical Sections</a><ul>
<li><a class="reference internal" href="#what-are-critical-sections">What Are Critical Sections?</a></li>
<li><a class="reference internal" href="#using-critical-sections">Using Critical Sections</a></li>
<li><a class="reference internal" href="#how-critical-sections-work">How Critical Sections Work</a></li>
<li><a class="reference internal" href="#deadlock-avoidance">Deadlock Avoidance</a></li>
<li><a class="reference internal" href="#important-considerations">Important Considerations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#building-extensions-for-the-free-threaded-build">Building Extensions for the Free-Threaded Build</a><ul>
<li><a class="reference internal" href="#limited-c-api-and-stable-abi">Limited C API and Stable ABI</a></li>
<li><a class="reference internal" href="#windows">Windows</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  </div>
  <div>
    <h4>Previous topic</h4>
    <p class="topless"><a href="free-threading-python.html"
                          title="previous chapter">Python support for free threading</a></p>
  </div>
  <div>
    <h4>Next topic</h4>
    <p class="topless"><a href="remote_debugging.html"
                          title="next chapter">Remote debugging attachment protocol</a></p>
  </div>
  <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 href="https://github.com/python/cpython/blob/main/Doc/howto/free-threading-extensions.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="remote_debugging.html" title="Remote debugging attachment protocol"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="free-threading-python.html" title="Python support for free threading"
             accesskey="P">previous</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.14.0 Documentation</a> &#187;
    </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">C API Extension Support for Free Threading</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="c-api-extension-support-for-free-threading">
<span id="freethreading-extensions-howto"></span><h1>C API Extension Support for Free Threading<a class="headerlink" href="#c-api-extension-support-for-free-threading" title="Link to this heading">¶</a></h1>
<p>Starting with the 3.13 release, CPython has support for running with
the <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a> (GIL) disabled in a configuration
called <a class="reference internal" href="../glossary.html#term-free-threading"><span class="xref std std-term">free threading</span></a>.  This document describes how to adapt C API
extensions to support free threading.</p>
<section id="identifying-the-free-threaded-build-in-c">
<h2>Identifying the Free-Threaded Build in C<a class="headerlink" href="#identifying-the-free-threaded-build-in-c" title="Link to this heading">¶</a></h2>
<p>The CPython C API exposes the <code class="docutils literal notranslate"><span class="pre">Py_GIL_DISABLED</span></code> macro: in the free-threaded
build it’s defined to <code class="docutils literal notranslate"><span class="pre">1</span></code>, and in the regular build it’s not defined.
You can use it to enable code that only runs under the free-threaded build:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef Py_GIL_DISABLED</span>
<span class="cm">/* code that only runs in the free-threaded build */</span>
<span class="cp">#endif</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>On Windows, this macro is not defined automatically, but must be specified
to the compiler when building. The <a class="reference internal" href="../library/sysconfig.html#sysconfig.get_config_var" title="sysconfig.get_config_var"><code class="xref py py-func docutils literal notranslate"><span class="pre">sysconfig.get_config_var()</span></code></a> function
can be used to determine whether the current running interpreter had the
macro defined.</p>
</div>
</section>
<section id="module-initialization">
<h2>Module Initialization<a class="headerlink" href="#module-initialization" title="Link to this heading">¶</a></h2>
<p>Extension modules need to explicitly indicate that they support running with
the GIL disabled; otherwise importing the extension will raise a warning and
enable the GIL at runtime.</p>
<p>There are two ways to indicate that an extension module supports running with
the GIL disabled depending on whether the extension uses multi-phase or
single-phase initialization.</p>
<section id="multi-phase-initialization">
<h3>Multi-Phase Initialization<a class="headerlink" href="#multi-phase-initialization" title="Link to this heading">¶</a></h3>
<p>Extensions that use multi-phase initialization (i.e.,
<a class="reference internal" href="../c-api/extension-modules.html#c.PyModuleDef_Init" title="PyModuleDef_Init"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyModuleDef_Init()</span></code></a>) should add a <a class="reference internal" href="../c-api/module.html#c.Py_mod_gil" title="Py_mod_gil"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_mod_gil</span></code></a> slot in the
module definition.  If your extension supports older versions of CPython,
you should guard the slot with a <a class="reference internal" href="../c-api/apiabiversion.html#c.PY_VERSION_HEX" title="PY_VERSION_HEX"><code class="xref c c-data docutils literal notranslate"><span class="pre">PY_VERSION_HEX</span></code></a> check.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyModuleDef_Slot</span><span class="w"> </span><span class="n">module_slots</span><span class="p">[]</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="cp">#if PY_VERSION_HEX &gt;= 0x030D0000</span>
<span class="w">    </span><span class="p">{</span><span class="n">Py_mod_gil</span><span class="p">,</span><span class="w"> </span><span class="n">Py_MOD_GIL_NOT_USED</span><span class="p">},</span>
<span class="cp">#endif</span>
<span class="w">    </span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">}</span>
<span class="p">};</span>

<span class="k">static</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyModuleDef</span><span class="w"> </span><span class="n">moduledef</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="n">PyModuleDef_HEAD_INIT</span><span class="p">,</span>
<span class="w">    </span><span class="p">.</span><span class="n">m_slots</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">module_slots</span><span class="p">,</span>
<span class="w">    </span><span class="p">...</span>
<span class="p">};</span>
</pre></div>
</div>
</section>
<section id="single-phase-initialization">
<h3>Single-Phase Initialization<a class="headerlink" href="#single-phase-initialization" title="Link to this heading">¶</a></h3>
<p>Extensions that use single-phase initialization (i.e.,
<a class="reference internal" href="../c-api/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>) should call <a class="reference internal" href="../c-api/module.html#c.PyUnstable_Module_SetGIL" title="PyUnstable_Module_SetGIL"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyUnstable_Module_SetGIL()</span></code></a> to
indicate that they support running with the GIL disabled.  The function is
only defined in the free-threaded build, so you should guard the call with
<code class="docutils literal notranslate"><span class="pre">#ifdef</span> <span class="pre">Py_GIL_DISABLED</span></code> to avoid compilation errors in the regular build.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyModuleDef</span><span class="w"> </span><span class="n">moduledef</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="n">PyModuleDef_HEAD_INIT</span><span class="p">,</span>
<span class="w">    </span><span class="p">...</span>
<span class="p">};</span>

<span class="n">PyMODINIT_FUNC</span>
<span class="nf">PyInit_mymodule</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w">    </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">m</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyModule_Create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">moduledef</span><span class="p">);</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">m</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="w">    </span><span class="p">}</span>
<span class="cp">#ifdef Py_GIL_DISABLED</span>
<span class="w">    </span><span class="n">PyUnstable_Module_SetGIL</span><span class="p">(</span><span class="n">m</span><span class="p">,</span><span class="w"> </span><span class="n">Py_MOD_GIL_NOT_USED</span><span class="p">);</span>
<span class="cp">#endif</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">m</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
<section id="general-api-guidelines">
<h2>General API Guidelines<a class="headerlink" href="#general-api-guidelines" title="Link to this heading">¶</a></h2>
<p>Most of the C API is thread-safe, but there are some exceptions.</p>
<ul class="simple">
<li><p><strong>Struct Fields</strong>: Accessing fields in Python C API objects or structs
directly is not thread-safe if the field may be concurrently modified.</p></li>
<li><p><strong>Macros</strong>: Accessor macros like <a class="reference internal" href="../c-api/list.html#c.PyList_GET_ITEM" title="PyList_GET_ITEM"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyList_GET_ITEM</span></code></a>,
<a class="reference internal" href="../c-api/list.html#c.PyList_SET_ITEM" title="PyList_SET_ITEM"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyList_SET_ITEM</span></code></a>, and macros like
<a class="reference internal" href="../c-api/sequence.html#c.PySequence_Fast_GET_SIZE" title="PySequence_Fast_GET_SIZE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PySequence_Fast_GET_SIZE</span></code></a> that use the object returned by
<a class="reference internal" href="../c-api/sequence.html#c.PySequence_Fast" title="PySequence_Fast"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_Fast()</span></code></a> do not perform any error checking or locking.
These macros are not thread-safe if the container object may be modified
concurrently.</p></li>
<li><p><strong>Borrowed References</strong>: C API functions that return
<a class="reference internal" href="../glossary.html#term-borrowed-reference"><span class="xref std std-term">borrowed references</span></a> may not be thread-safe if
the containing object is modified concurrently.  See the section on
<a class="reference internal" href="#id2"><span class="std std-ref">borrowed references</span></a> for more information.</p></li>
</ul>
<section id="container-thread-safety">
<h3>Container Thread Safety<a class="headerlink" href="#container-thread-safety" title="Link to this heading">¶</a></h3>
<p>Containers like <a class="reference internal" href="../c-api/list.html#c.PyListObject" title="PyListObject"><code class="xref c c-struct docutils literal notranslate"><span class="pre">PyListObject</span></code></a>,
<a class="reference internal" href="../c-api/dict.html#c.PyDictObject" title="PyDictObject"><code class="xref c c-struct docutils literal notranslate"><span class="pre">PyDictObject</span></code></a>, and <a class="reference internal" href="../c-api/set.html#c.PySetObject" title="PySetObject"><code class="xref c c-struct docutils literal notranslate"><span class="pre">PySetObject</span></code></a> perform internal locking
in the free-threaded build.  For example, the <a class="reference internal" href="../c-api/list.html#c.PyList_Append" title="PyList_Append"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_Append()</span></code></a> will
lock the list before appending an item.</p>
<section id="pydict-next">
<span id="id1"></span><h4><code class="docutils literal notranslate"><span class="pre">PyDict_Next</span></code><a class="headerlink" href="#pydict-next" title="Link to this heading">¶</a></h4>
<p>A notable exception is <a class="reference internal" href="../c-api/dict.html#c.PyDict_Next" title="PyDict_Next"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_Next()</span></code></a>, which does not lock the
dictionary.  You should use <a class="reference internal" href="../c-api/init.html#c.Py_BEGIN_CRITICAL_SECTION" title="Py_BEGIN_CRITICAL_SECTION"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_CRITICAL_SECTION</span></code></a> to protect
the dictionary while iterating over it if the dictionary may be concurrently
modified:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Py_BEGIN_CRITICAL_SECTION</span><span class="p">(</span><span class="n">dict</span><span class="p">);</span>
<span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">value</span><span class="p">;</span>
<span class="n">Py_ssize_t</span><span class="w"> </span><span class="n">pos</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">PyDict_Next</span><span class="p">(</span><span class="n">dict</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">pos</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">value</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="p">...</span>
<span class="p">}</span>
<span class="n">Py_END_CRITICAL_SECTION</span><span class="p">();</span>
</pre></div>
</div>
</section>
</section>
</section>
<section id="borrowed-references">
<h2>Borrowed References<a class="headerlink" href="#borrowed-references" title="Link to this heading">¶</a></h2>
<p id="id2">Some C API functions return <a class="reference internal" href="../glossary.html#term-borrowed-reference"><span class="xref std std-term">borrowed references</span></a>.
These APIs are not thread-safe if the containing object is modified
concurrently.  For example, it’s not safe to use <a class="reference internal" href="../c-api/list.html#c.PyList_GetItem" title="PyList_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItem()</span></code></a>
if the list may be modified concurrently.</p>
<p>The following table lists some borrowed reference APIs and their replacements
that return <a class="reference internal" href="../glossary.html#term-strong-reference"><span class="xref std std-term">strong references</span></a>.</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Borrowed reference API</p></th>
<th class="head"><p>Strong reference API</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/list.html#c.PyList_GetItem" title="PyList_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItem()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/list.html#c.PyList_GetItemRef" title="PyList_GetItemRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItemRef()</span></code></a></p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="../c-api/list.html#c.PyList_GET_ITEM" title="PyList_GET_ITEM"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GET_ITEM()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/list.html#c.PyList_GetItemRef" title="PyList_GetItemRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItemRef()</span></code></a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItem" title="PyDict_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItem()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItemRef" title="PyDict_GetItemRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItemRef()</span></code></a></p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItemWithError" title="PyDict_GetItemWithError"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItemWithError()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItemRef" title="PyDict_GetItemRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItemRef()</span></code></a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItemString" title="PyDict_GetItemString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItemString()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItemStringRef" title="PyDict_GetItemStringRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItemStringRef()</span></code></a></p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_SetDefault" title="PyDict_SetDefault"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_SetDefault()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_SetDefaultRef" title="PyDict_SetDefaultRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_SetDefaultRef()</span></code></a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/dict.html#c.PyDict_Next" title="PyDict_Next"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_Next()</span></code></a></p></td>
<td><p>none (see <a class="reference internal" href="#pydict-next"><span class="std std-ref">PyDict_Next</span></a>)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="../c-api/weakref.html#c.PyWeakref_GetObject" title="PyWeakref_GetObject"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyWeakref_GetObject()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/weakref.html#c.PyWeakref_GetRef" title="PyWeakref_GetRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyWeakref_GetRef()</span></code></a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/weakref.html#c.PyWeakref_GET_OBJECT" title="PyWeakref_GET_OBJECT"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyWeakref_GET_OBJECT()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/weakref.html#c.PyWeakref_GetRef" title="PyWeakref_GetRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyWeakref_GetRef()</span></code></a></p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="../c-api/import.html#c.PyImport_AddModule" title="PyImport_AddModule"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyImport_AddModule()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/import.html#c.PyImport_AddModuleRef" title="PyImport_AddModuleRef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyImport_AddModuleRef()</span></code></a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="../c-api/cell.html#c.PyCell_GET" title="PyCell_GET"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyCell_GET()</span></code></a></p></td>
<td><p><a class="reference internal" href="../c-api/cell.html#c.PyCell_Get" title="PyCell_Get"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyCell_Get()</span></code></a></p></td>
</tr>
</tbody>
</table>
<p>Not all APIs that return borrowed references are problematic.  For
example, <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_GetItem" title="PyTuple_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_GetItem()</span></code></a> is safe because tuples are immutable.
Similarly, not all uses of the above APIs are problematic.  For example,
<a class="reference internal" href="../c-api/dict.html#c.PyDict_GetItem" title="PyDict_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_GetItem()</span></code></a> is often used for parsing keyword argument
dictionaries in function calls; those keyword argument dictionaries are
effectively private (not accessible by other threads), so using borrowed
references in that context is safe.</p>
<p>Some of these functions were added in Python 3.13.  You can use the
<a class="reference external" href="https://github.com/python/pythoncapi-compat">pythoncapi-compat</a> package
to provide implementations of these functions for older Python versions.</p>
</section>
<section id="memory-allocation-apis">
<span id="free-threaded-memory-allocation"></span><h2>Memory Allocation APIs<a class="headerlink" href="#memory-allocation-apis" title="Link to this heading">¶</a></h2>
<p>Python’s memory management C API provides functions in three different
<a class="reference internal" href="../c-api/memory.html#id1"><span class="std std-ref">allocation domains</span></a>: “raw”, “mem”, and “object”.
For thread-safety, the free-threaded build requires that only Python objects
are allocated using the object domain, and that all Python object are
allocated using that domain.  This differs from the prior Python versions,
where this was only a best practice and not a hard requirement.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Search for uses of <a class="reference internal" href="../c-api/memory.html#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a> in your
extension and check that the allocated memory is used for Python objects.
Use <a class="reference internal" href="../c-api/memory.html#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a> to allocate buffers instead of
<a class="reference internal" href="../c-api/memory.html#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a>.</p>
</div>
</section>
<section id="thread-state-and-gil-apis">
<h2>Thread State and GIL APIs<a class="headerlink" href="#thread-state-and-gil-apis" title="Link to this heading">¶</a></h2>
<p>Python provides a set of functions and macros to manage thread state and the
GIL, such as:</p>
<ul class="simple">
<li><p><a class="reference internal" href="../c-api/init.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="../c-api/init.html#c.PyGILState_Release" title="PyGILState_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Release()</span></code></a></p></li>
<li><p><a class="reference internal" href="../c-api/init.html#c.PyEval_SaveThread" title="PyEval_SaveThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SaveThread()</span></code></a> and <a class="reference internal" href="../c-api/init.html#c.PyEval_RestoreThread" title="PyEval_RestoreThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_RestoreThread()</span></code></a></p></li>
<li><p><a class="reference internal" href="../c-api/init.html#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> and <a class="reference internal" href="../c-api/init.html#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></li>
</ul>
<p>These functions should still be used in the free-threaded build to manage
thread state even when the <a class="reference internal" href="../glossary.html#term-GIL"><span class="xref std std-term">GIL</span></a> is disabled.  For example, if you
create a thread outside of Python, you must call <a class="reference internal" href="../c-api/init.html#c.PyGILState_Ensure" title="PyGILState_Ensure"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyGILState_Ensure()</span></code></a>
before calling into the Python API to ensure that the thread has a valid
Python thread state.</p>
<p>You should continue to call <a class="reference internal" href="../c-api/init.html#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-api/init.html#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> around blocking operations, such as I/O or
lock acquisitions, to allow other threads to run the
<a class="reference internal" href="../glossary.html#term-garbage-collection"><span class="xref std std-term">cyclic garbage collector</span></a>.</p>
</section>
<section id="protecting-internal-extension-state">
<h2>Protecting Internal Extension State<a class="headerlink" href="#protecting-internal-extension-state" title="Link to this heading">¶</a></h2>
<p>Your extension may have internal state that was previously protected by the
GIL.  You may need to add locking to protect this state.  The approach will
depend on your extension, but some common patterns include:</p>
<ul class="simple">
<li><p><strong>Caches</strong>: global caches are a common source of shared state.  Consider
using a lock to protect the cache or disabling it in the free-threaded build
if the cache is not critical for performance.</p></li>
<li><p><strong>Global State</strong>: global state may need to be protected by a lock or moved
to thread local storage. C11 and C++11 provide the <code class="docutils literal notranslate"><span class="pre">thread_local</span></code> or
<code class="docutils literal notranslate"><span class="pre">_Thread_local</span></code> for
<a class="reference external" href="https://en.cppreference.com/w/c/language/storage_duration">thread-local storage</a>.</p></li>
</ul>
</section>
<section id="critical-sections">
<h2>Critical Sections<a class="headerlink" href="#critical-sections" title="Link to this heading">¶</a></h2>
<p id="id3">In the free-threaded build, CPython provides a mechanism called “critical
sections” to protect data that would otherwise be protected by the GIL.
While extension authors may not interact with the internal critical section
implementation directly, understanding their behavior is crucial when using
certain C API functions or managing shared state in the free-threaded build.</p>
<section id="what-are-critical-sections">
<h3>What Are Critical Sections?<a class="headerlink" href="#what-are-critical-sections" title="Link to this heading">¶</a></h3>
<p>Conceptually, critical sections act as a deadlock avoidance layer built on
top of simple mutexes. Each thread maintains a stack of active critical
sections. When a thread needs to acquire a lock associated with a critical
section (e.g., implicitly when calling a thread-safe C API function like
<a class="reference internal" href="../c-api/dict.html#c.PyDict_SetItem" title="PyDict_SetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyDict_SetItem()</span></code></a>, or explicitly using macros), it attempts to acquire
the underlying mutex.</p>
</section>
<section id="using-critical-sections">
<h3>Using Critical Sections<a class="headerlink" href="#using-critical-sections" title="Link to this heading">¶</a></h3>
<p>The primary APIs for using critical sections are:</p>
<ul class="simple">
<li><p><a class="reference internal" href="../c-api/init.html#c.Py_BEGIN_CRITICAL_SECTION" title="Py_BEGIN_CRITICAL_SECTION"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_CRITICAL_SECTION</span></code></a> and <a class="reference internal" href="../c-api/init.html#c.Py_END_CRITICAL_SECTION" title="Py_END_CRITICAL_SECTION"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_CRITICAL_SECTION</span></code></a> -
For locking a single object</p></li>
<li><p><a class="reference internal" href="../c-api/init.html#c.Py_BEGIN_CRITICAL_SECTION2" title="Py_BEGIN_CRITICAL_SECTION2"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_CRITICAL_SECTION2</span></code></a> and <a class="reference internal" href="../c-api/init.html#c.Py_END_CRITICAL_SECTION2" title="Py_END_CRITICAL_SECTION2"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_END_CRITICAL_SECTION2</span></code></a>
- For locking two objects simultaneously</p></li>
</ul>
<p>These macros must be used in matching pairs and must appear in the same C
scope, since they establish a new local scope.  These macros are no-ops in
non-free-threaded builds, so they can be safely added to code that needs to
support both build types.</p>
<p>A common use of a critical section would be to lock an object while accessing
an internal attribute of it.  For example, if an extension type has an internal
count field, you could use a critical section while reading or writing that
field:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="c1">// read the count, returns new reference to internal count value</span>
<span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">result</span><span class="p">;</span>
<span class="n">Py_BEGIN_CRITICAL_SECTION</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
<span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_NewRef</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">count</span><span class="p">);</span>
<span class="n">Py_END_CRITICAL_SECTION</span><span class="p">();</span>
<span class="k">return</span><span class="w"> </span><span class="n">result</span><span class="p">;</span>

<span class="c1">// write the count, consumes reference from new_count</span>
<span class="n">Py_BEGIN_CRITICAL_SECTION</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">count</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new_count</span><span class="p">;</span>
<span class="n">Py_END_CRITICAL_SECTION</span><span class="p">();</span>
</pre></div>
</div>
</section>
<section id="how-critical-sections-work">
<h3>How Critical Sections Work<a class="headerlink" href="#how-critical-sections-work" title="Link to this heading">¶</a></h3>
<p>Unlike traditional locks, critical sections do not guarantee exclusive access
throughout their entire duration. If a thread would block while holding a
critical section (e.g., by acquiring another lock or performing I/O), the
critical section is temporarily suspended—all locks are released—and then
resumed when the blocking operation completes.</p>
<p>This behavior is similar to what happens with the GIL when a thread makes a
blocking call. The key differences are:</p>
<ul class="simple">
<li><p>Critical sections operate on a per-object basis rather than globally</p></li>
<li><p>Critical sections follow a stack discipline within each thread (the “begin” and
“end” macros enforce this since they must be paired and within the same scope)</p></li>
<li><p>Critical sections automatically release and reacquire locks around potential
blocking operations</p></li>
</ul>
</section>
<section id="deadlock-avoidance">
<h3>Deadlock Avoidance<a class="headerlink" href="#deadlock-avoidance" title="Link to this heading">¶</a></h3>
<p>Critical sections help avoid deadlocks in two ways:</p>
<ol class="arabic simple">
<li><p>If a thread tries to acquire a lock that’s already held by another thread,
it first suspends all of its active critical sections, temporarily releasing
their locks</p></li>
<li><p>When the blocking operation completes, only the top-most critical section is
reacquired first</p></li>
</ol>
<p>This means you cannot rely on nested critical sections to lock multiple objects
at once, as the inner critical section may suspend the outer ones. Instead, use
<a class="reference internal" href="../c-api/init.html#c.Py_BEGIN_CRITICAL_SECTION2" title="Py_BEGIN_CRITICAL_SECTION2"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_CRITICAL_SECTION2</span></code></a> to lock two objects simultaneously.</p>
<p>Note that the locks described above are only <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> based locks.
The critical section implementation does not know about or affect other locking
mechanisms that might be in use, like POSIX mutexes.  Also note that while
blocking on any <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> causes the critical sections to be
suspended, only the mutexes that are part of the critical sections are
released.  If <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> is used without a critical section, it will
not be released and therefore does not get the same deadlock avoidance.</p>
</section>
<section id="important-considerations">
<h3>Important Considerations<a class="headerlink" href="#important-considerations" title="Link to this heading">¶</a></h3>
<ul class="simple">
<li><p>Critical sections may temporarily release their locks, allowing other threads
to modify the protected data. Be careful about making assumptions about the
state of the data after operations that might block.</p></li>
<li><p>Because locks can be temporarily released (suspended), entering a critical
section does not guarantee exclusive access to the protected resource
throughout the section’s duration. If code within a critical section calls
another function that blocks (e.g., acquires another lock, performs blocking
I/O), all locks held by the thread via critical sections will be released.
This is similar to how the GIL can be released during blocking calls.</p></li>
<li><p>Only the lock(s) associated with the most recently entered (top-most)
critical section are guaranteed to be held at any given time. Locks for
outer, nested critical sections might have been suspended.</p></li>
<li><p>You can lock at most two objects simultaneously with these APIs. If you need
to lock more objects, you’ll need to restructure your code.</p></li>
<li><p>While critical sections will not deadlock if you attempt to lock the same
object twice, they are less efficient than purpose-built reentrant locks for
this use case.</p></li>
<li><p>When using <a class="reference internal" href="../c-api/init.html#c.Py_BEGIN_CRITICAL_SECTION2" title="Py_BEGIN_CRITICAL_SECTION2"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_BEGIN_CRITICAL_SECTION2</span></code></a>, the order of the objects
doesn’t affect correctness (the implementation handles deadlock avoidance),
but it’s good practice to always lock objects in a consistent order.</p></li>
<li><p>Remember that the critical section macros are primarily for protecting access
to <em>Python objects</em> that might be involved in internal CPython operations
susceptible to the deadlock scenarios described above. For protecting purely
internal extension state, standard mutexes or other synchronization
primitives might be more appropriate.</p></li>
</ul>
</section>
</section>
<section id="building-extensions-for-the-free-threaded-build">
<h2>Building Extensions for the Free-Threaded Build<a class="headerlink" href="#building-extensions-for-the-free-threaded-build" title="Link to this heading">¶</a></h2>
<p>C API extensions need to be built specifically for the free-threaded build.
The wheels, shared libraries, and binaries are indicated by a <code class="docutils literal notranslate"><span class="pre">t</span></code> suffix.</p>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/pypa/manylinux">pypa/manylinux</a> supports the
free-threaded build, with the <code class="docutils literal notranslate"><span class="pre">t</span></code> suffix, such as <code class="docutils literal notranslate"><span class="pre">python3.13t</span></code>.</p></li>
<li><p><a class="reference external" href="https://github.com/pypa/cibuildwheel">pypa/cibuildwheel</a> supports the
free-threaded build if you set
<a class="reference external" href="https://cibuildwheel.pypa.io/en/stable/options/#enable">CIBW_ENABLE to cpython-freethreading</a>.</p></li>
</ul>
<section id="limited-c-api-and-stable-abi">
<h3>Limited C API and Stable ABI<a class="headerlink" href="#limited-c-api-and-stable-abi" title="Link to this heading">¶</a></h3>
<p>The free-threaded build does not currently support the
<a class="reference internal" href="../c-api/stable.html#limited-c-api"><span class="std std-ref">Limited C API</span></a> or the stable ABI.  If you use
<a class="reference external" href="https://setuptools.pypa.io/en/latest/setuptools.html">setuptools</a> to build
your extension and currently set <code class="docutils literal notranslate"><span class="pre">py_limited_api=True</span></code> you can use
<code class="docutils literal notranslate"><span class="pre">py_limited_api=not</span> <span class="pre">sysconfig.get_config_var(&quot;Py_GIL_DISABLED&quot;)</span></code> to opt out
of the limited API when building with the free-threaded build.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>You will need to build separate wheels specifically for the free-threaded
build.  If you currently use the stable ABI, you can continue to build a
single wheel for multiple non-free-threaded Python versions.</p>
</div>
</section>
<section id="windows">
<h3>Windows<a class="headerlink" href="#windows" title="Link to this heading">¶</a></h3>
<p>Due to a limitation of the official Windows installer, you will need to
manually define <code class="docutils literal notranslate"><span class="pre">Py_GIL_DISABLED=1</span></code> when building extensions from source.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference external" href="https://py-free-threading.github.io/porting/">Porting Extension Modules to Support Free-Threading</a>:
A community-maintained porting guide for extension authors.</p>
</div>
</section>
</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="#">C API Extension Support for Free Threading</a><ul>
<li><a class="reference internal" href="#identifying-the-free-threaded-build-in-c">Identifying the Free-Threaded Build in C</a></li>
<li><a class="reference internal" href="#module-initialization">Module Initialization</a><ul>
<li><a class="reference internal" href="#multi-phase-initialization">Multi-Phase Initialization</a></li>
<li><a class="reference internal" href="#single-phase-initialization">Single-Phase Initialization</a></li>
</ul>
</li>
<li><a class="reference internal" href="#general-api-guidelines">General API Guidelines</a><ul>
<li><a class="reference internal" href="#container-thread-safety">Container Thread Safety</a><ul>
<li><a class="reference internal" href="#pydict-next"><code class="docutils literal notranslate"><span class="pre">PyDict_Next</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#borrowed-references">Borrowed References</a></li>
<li><a class="reference internal" href="#memory-allocation-apis">Memory Allocation APIs</a></li>
<li><a class="reference internal" href="#thread-state-and-gil-apis">Thread State and GIL APIs</a></li>
<li><a class="reference internal" href="#protecting-internal-extension-state">Protecting Internal Extension State</a></li>
<li><a class="reference internal" href="#critical-sections">Critical Sections</a><ul>
<li><a class="reference internal" href="#what-are-critical-sections">What Are Critical Sections?</a></li>
<li><a class="reference internal" href="#using-critical-sections">Using Critical Sections</a></li>
<li><a class="reference internal" href="#how-critical-sections-work">How Critical Sections Work</a></li>
<li><a class="reference internal" href="#deadlock-avoidance">Deadlock Avoidance</a></li>
<li><a class="reference internal" href="#important-considerations">Important Considerations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#building-extensions-for-the-free-threaded-build">Building Extensions for the Free-Threaded Build</a><ul>
<li><a class="reference internal" href="#limited-c-api-and-stable-abi">Limited C API and Stable ABI</a></li>
<li><a class="reference internal" href="#windows">Windows</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  </div>
  <div>
    <h4>Previous topic</h4>
    <p class="topless"><a href="free-threading-python.html"
                          title="previous chapter">Python support for free threading</a></p>
  </div>
  <div>
    <h4>Next topic</h4>
    <p class="topless"><a href="remote_debugging.html"
                          title="next chapter">Remote debugging attachment protocol</a></p>
  </div>
  <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 href="https://github.com/python/cpython/blob/main/Doc/howto/free-threading-extensions.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="remote_debugging.html" title="Remote debugging attachment protocol"
             >next</a> |</li>
        <li class="right" >
          <a href="free-threading-python.html" title="Python support for free threading"
             >previous</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.14.0 Documentation</a> &#187;
    </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">C API Extension Support for Free Threading</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">
    &copy; <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 07, 2025 (10:02 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>