| Server IP : 121.121.20.254 / Your IP : 216.73.217.51 Web Server : Microsoft-IIS/10.0 System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64 User : IUSR ( 0) PHP Version : 8.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Python315/Doc/html/c-api/ |
Upload File : |
<!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="Synchronization primitives" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/c-api/synchronization.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="The C-API provides a basic mutual exclusion lock. Python critical section API: The critical section API provides a deadlock avoidance layer on top of per-object locks for free-threaded CPython. The..." />
<meta property="og:image" content="_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="The C-API provides a basic mutual exclusion lock. Python critical section API: The critical section API provides a deadlock avoidance layer on top of per-object locks for free-threaded CPython. The..." />
<meta name="theme-color" content="#3776ab">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<title>Synchronization primitives — Python 3.15.0rc1 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=4365c8fe" />
<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=791e38b1"></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.0rc1 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="Thread-local storage support" href="tls.html" />
<link rel="prev" title="Thread states and the global interpreter lock" href="threads.html" />
<link rel="canonical" href="https://docs.python.org/3/c-api/synchronization.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="#">Synchronization primitives</a><ul>
<li><a class="reference internal" href="#python-critical-section-api">Python critical section API</a><ul>
<li><a class="reference internal" href="#low-level-critical-section-api">Low-level critical section API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#legacy-locking-apis">Legacy locking APIs</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="threads.html"
title="previous chapter">Thread states and the global interpreter lock</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="tls.html"
title="next chapter">Thread-local storage support</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/synchronization.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/main/Doc/c-api/synchronization.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="tls.html" title="Thread-local storage support"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="threads.html" title="Thread states and the global interpreter lock"
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> »</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.0rc1 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="">Synchronization primitives</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="synchronization-primitives">
<span id="synchronization"></span><h1>Synchronization primitives<a class="headerlink" href="#synchronization-primitives" title="Link to this heading">¶</a></h1>
<p>The C-API provides a basic mutual exclusion lock.</p>
<dl class="c type">
<dt class="sig sig-object c" id="c.PyMutex">
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyMutex</span></span></span><a class="headerlink" href="#c.PyMutex" title="Link to this definition">¶</a><br /></dt>
<dd><p>A mutual exclusion lock. The <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> should be initialized to
zero to represent the unlocked state. For example:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyMutex</span><span class="w"> </span><span class="n">mutex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</pre></div>
</div>
<p>Instances of <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> should not be copied or moved. Both the
contents and address of a <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> are meaningful, and it must
remain at a fixed, writable location in memory.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>A <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code> currently occupies one byte, but the size should be
considered unstable. The size may change in future Python releases
without a deprecation period.</p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyMutex_Lock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyMutex_Lock</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMutex_Lock" title="Link to this definition">¶</a><br /></dt>
<dd><em class="threadsafety threadsafety-atomic"> Thread safety: <a class="reference internal" href="../library/threadsafety.html#threadsafety-level-atomic"><span class="std std-ref">Atomic</span></a>.</em><p>Lock mutex <em>m</em>. If another thread has already locked it, the calling
thread will block until the mutex is unlocked. While blocked, the thread
will temporarily detach the <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">thread state</span></a> if one exists.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyMutex_Unlock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyMutex_Unlock</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMutex_Unlock" title="Link to this definition">¶</a><br /></dt>
<dd><em class="threadsafety threadsafety-atomic"> Thread safety: <a class="reference internal" href="../library/threadsafety.html#threadsafety-level-atomic"><span class="std std-ref">Atomic</span></a>.</em><p>Unlock mutex <em>m</em>. The mutex must be locked — otherwise, the function will
issue a fatal error.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyMutex_IsLocked">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyMutex_IsLocked</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMutex_IsLocked" title="Link to this definition">¶</a><br /></dt>
<dd><em class="threadsafety threadsafety-atomic"> Thread safety: <a class="reference internal" href="../library/threadsafety.html#threadsafety-level-atomic"><span class="std std-ref">Atomic</span></a>.</em><p>Returns non-zero if the mutex <em>m</em> is currently locked, zero otherwise.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This function is intended for use in assertions and debugging only and
should not be used to make concurrency control decisions, as the lock
state may change immediately after the check.</p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.14.</span></p>
</div>
</dd></dl>
<section id="python-critical-section-api">
<span id="id1"></span><h2>Python critical section API<a class="headerlink" href="#python-critical-section-api" title="Link to this heading">¶</a></h2>
<p>The critical section API provides a deadlock avoidance layer on top of
per-object locks for <a class="reference internal" href="../glossary.html#term-free-threading"><span class="xref std std-term">free-threaded</span></a> CPython. They are
intended to replace reliance on the <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a>, and are
no-ops in versions of Python with the global interpreter lock.</p>
<p>Critical sections are intended to be used for custom types implemented
in C-API extensions. They should generally not be used with built-in types like
<a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> and <a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> because their public C-APIs
already use critical sections internally, with the notable
exception of <a class="reference internal" href="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 requires critical section
to be acquired externally.</p>
<p>Critical sections avoid deadlocks by implicitly suspending active critical
sections, hence, they do not provide exclusive access such as provided by
traditional locks like <a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a>. When a critical section is started,
the per-object lock for the object is acquired. If the code executed inside the
critical section calls C-API functions then it can suspend the critical section thereby
releasing the per-object lock, so other threads can acquire the per-object lock
for the same object.</p>
<p>Variants that accept <a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a> pointers rather than Python objects are also
available. Use these variants to start a critical section in a situation where
there is no <a class="reference internal" href="structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span></code></a> – for example, when working with a C type that
does not extend or wrap <code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span></code> but still needs to call into the C
API in a manner that might lead to deadlocks.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Operations that need to lock two objects at once must use
<a class="reference internal" href="#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>. You <em>cannot</em> use nested critical
sections to lock more than one object at once, because the inner critical
section may suspend the outer critical sections. This API does not provide
a way to lock more than two objects at once.</p>
</div>
<p>Example usage:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">set_field</span><span class="p">(</span><span class="n">MyObject</span><span class="w"> </span><span class="o">*</span><span class="n">self</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">value</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">Py_BEGIN_CRITICAL_SECTION</span><span class="p">(</span><span class="n">self</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_SETREF</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">field</span><span class="p">,</span><span class="w"> </span><span class="n">Py_XNewRef</span><span class="p">(</span><span class="n">value</span><span class="p">));</span>
<span class="w"> </span><span class="n">Py_END_CRITICAL_SECTION</span><span class="p">();</span>
<span class="w"> </span><span class="n">Py_RETURN_NONE</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In the above example, <a class="reference internal" href="refcounting.html#c.Py_SETREF" title="Py_SETREF"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_SETREF</span></code></a> calls <a class="reference internal" href="refcounting.html#c.Py_DECREF" title="Py_DECREF"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_DECREF</span></code></a>, which
can call arbitrary code through an object’s deallocation function. The critical
section API avoids potential deadlocks due to reentrancy and lock ordering
by allowing the runtime to temporarily suspend the critical section if the
code triggered by the finalizer blocks and calls <a class="reference internal" href="threads.html#c.PyEval_SaveThread" title="PyEval_SaveThread"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_SaveThread()</span></code></a>.</p>
<dl class="c macro" id="critical-section-macros">
<dt class="sig sig-object c" id="c.Py_BEGIN_CRITICAL_SECTION">
<span class="sig-name descname"><span class="n"><span class="pre">Py_BEGIN_CRITICAL_SECTION</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">op</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_BEGIN_CRITICAL_SECTION" 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.15.</em><p>Acquires the per-object lock for the object <em>op</em> and begins a
critical section.</p>
<p>In the free-threaded build, and when building for the
<a class="reference internal" href="stable.html#stable-abi"><span class="std std-ref">Stable ABI</span></a>, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="n">PyCriticalSection</span><span class="w"> </span><span class="n">_py_cs</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyCriticalSection_Begin</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">PyObject</span><span class="o">*</span><span class="p">)(</span><span class="n">op</span><span class="p">))</span>
</pre></div>
</div>
<p>In the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">{</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c macro">
<dt class="sig sig-object c" id="c.Py_BEGIN_CRITICAL_SECTION_MUTEX">
<span class="sig-name descname"><span class="n"><span class="pre">Py_BEGIN_CRITICAL_SECTION_MUTEX</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">m</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_BEGIN_CRITICAL_SECTION_MUTEX" title="Link to this definition">¶</a><br /></dt>
<dd><p>Locks the mutex <em>m</em> and begins a critical section.</p>
<p>In the free-threaded build, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="n">PyCriticalSection</span><span class="w"> </span><span class="n">_py_cs</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyCriticalSection_BeginMutex</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs</span><span class="p">,</span><span class="w"> </span><span class="n">m</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that unlike <a class="reference internal" href="#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>, there is no cast for
the argument of the macro - it must be a <a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a> pointer.</p>
<p>On the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">{</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.14.</span></p>
</div>
</dd></dl>
<dl class="c macro">
<dt class="sig sig-object c" id="c.Py_END_CRITICAL_SECTION">
<span class="sig-name descname"><span class="n"><span class="pre">Py_END_CRITICAL_SECTION</span></span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_END_CRITICAL_SECTION" 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.15.</em><p>Ends the critical section and releases the per-object lock.</p>
<p>In the free-threaded build, and when building for the
<a class="reference internal" href="stable.html#stable-abi"><span class="std std-ref">Stable ABI</span></a>, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="n">PyCriticalSection_End</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">}</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c macro">
<dt class="sig sig-object c" id="c.Py_BEGIN_CRITICAL_SECTION2">
<span class="sig-name descname"><span class="n"><span class="pre">Py_BEGIN_CRITICAL_SECTION2</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">a</span></span>, <span class="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_BEGIN_CRITICAL_SECTION2" 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.15.</em><p>Acquires the per-object locks for the objects <em>a</em> and <em>b</em> and begins a
critical section. The locks are acquired in a consistent order (lowest
address first) to avoid lock ordering deadlocks.</p>
<p>In the free-threaded build, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="n">PyCriticalSection2</span><span class="w"> </span><span class="n">_py_cs2</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyCriticalSection2_Begin</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs2</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">PyObject</span><span class="o">*</span><span class="p">)(</span><span class="n">a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="n">PyObject</span><span class="o">*</span><span class="p">)(</span><span class="n">b</span><span class="p">))</span>
</pre></div>
</div>
<p>In the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">{</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c macro">
<dt class="sig sig-object c" id="c.Py_BEGIN_CRITICAL_SECTION2_MUTEX">
<span class="sig-name descname"><span class="n"><span class="pre">Py_BEGIN_CRITICAL_SECTION2_MUTEX</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">m1</span></span>, <span class="n"><span class="pre">m2</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_BEGIN_CRITICAL_SECTION2_MUTEX" title="Link to this definition">¶</a><br /></dt>
<dd><p>Locks the mutexes <em>m1</em> and <em>m2</em> and begins a critical section.</p>
<p>In the free-threaded build, and when building for the
<a class="reference internal" href="stable.html#stable-abi"><span class="std std-ref">Stable ABI</span></a>, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="n">PyCriticalSection2</span><span class="w"> </span><span class="n">_py_cs2</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyCriticalSection2_BeginMutex</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs2</span><span class="p">,</span><span class="w"> </span><span class="n">m1</span><span class="p">,</span><span class="w"> </span><span class="n">m2</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that unlike <a class="reference internal" href="#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>, there is no cast for
the arguments of the macro - they must be <a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a> pointers.</p>
<p>On the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">{</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.14.</span></p>
</div>
</dd></dl>
<dl class="c macro">
<dt class="sig sig-object c" id="c.Py_END_CRITICAL_SECTION2">
<span class="sig-name descname"><span class="n"><span class="pre">Py_END_CRITICAL_SECTION2</span></span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#c.Py_END_CRITICAL_SECTION2" 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.15.</em><p>Ends the critical section and releases the per-object locks.</p>
<p>In the free-threaded build, and when building for the
<a class="reference internal" href="stable.html#stable-abi"><span class="std std-ref">Stable ABI</span></a>, this macro expands to:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="n">PyCriticalSection2_End</span><span class="p">(</span><span class="o">&</span><span class="n">_py_cs2</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In the default build, this macro expands to <code class="docutils literal notranslate"><span class="pre">}</span></code>.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<section id="low-level-critical-section-api">
<h3>Low-level critical section API<a class="headerlink" href="#low-level-critical-section-api" title="Link to this heading">¶</a></h3>
<p>The following functions and structs are exposed for cases where C macros
are not available.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyCriticalSection_Begin">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection_Begin</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection" title="PyCriticalSection"><span class="n"><span class="pre">PyCriticalSection</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></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="n"><span class="pre">op</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyCriticalSection_Begin" title="Link to this definition">¶</a><br /></dt>
<dt class="sig sig-object c" id="c.PyCriticalSection_End">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection_End</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection" title="PyCriticalSection"><span class="n"><span class="pre">PyCriticalSection</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyCriticalSection_End" title="Link to this definition">¶</a><br /></dt>
<dt class="sig sig-object c" id="c.PyCriticalSection2_Begin">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection2_Begin</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection2" title="PyCriticalSection2"><span class="n"><span class="pre">PyCriticalSection2</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></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="n"><span class="pre">a</span></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="n"><span class="pre">b</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyCriticalSection2_Begin" title="Link to this definition">¶</a><br /></dt>
<dt class="sig sig-object c" id="c.PyCriticalSection2_End">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection2_End</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection2" title="PyCriticalSection2"><span class="n"><span class="pre">PyCriticalSection2</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.PyCriticalSection2_End" 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.15.</em><p>To be used only as in the macro expansions
listed <a class="reference internal" href="#critical-section-macros"><span class="std std-ref">earlier in this section</span></a>.</p>
<p>In non-<a class="reference internal" href="../glossary.html#term-free-threading"><span class="xref std std-term">free-threaded</span></a> builds of CPython, these
functions do nothing.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c type">
<dt class="sig sig-object c" id="c.PyCriticalSection">
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection</span></span></span><a class="headerlink" href="#c.PyCriticalSection" title="Link to this definition">¶</a><br /></dt>
<dt class="sig sig-object c" id="c.PyCriticalSection2">
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection2</span></span></span><a class="headerlink" href="#c.PyCriticalSection2" 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> (including all members) since version 3.15.</em><p>To be used only as in the macro expansions
listed <a class="reference internal" href="#critical-section-macros"><span class="std std-ref">earlier in this section</span></a>.
Note that the contents of the structures are private and their meaning may
change in future Python versions.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.13.</span></p>
</div>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyCriticalSection_BeginMutex">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection_BeginMutex</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection" title="PyCriticalSection"><span class="n"><span class="pre">PyCriticalSection</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></span>, <a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.PyCriticalSection_BeginMutex" title="Link to this definition">¶</a><br /></dt>
<dt class="sig sig-object c" id="c.PyCriticalSection2_BeginMutex">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyCriticalSection2_BeginMutex</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyCriticalSection2" title="PyCriticalSection2"><span class="n"><span class="pre">PyCriticalSection2</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">c</span></span>, <a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m1</span></span>, <a class="reference internal" href="#c.PyMutex" title="PyMutex"><span class="n"><span class="pre">PyMutex</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">m2</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.PyCriticalSection2_BeginMutex" title="Link to this definition">¶</a><br /></dt>
<dd><p>To be used only as in the macro expansions
listed <a class="reference internal" href="#critical-section-macros"><span class="std std-ref">earlier in this section</span></a>.</p>
<p>In non-<a class="reference internal" href="../glossary.html#term-free-threading"><span class="xref std std-term">free-threaded</span></a> builds of CPython, these
functions do nothing.</p>
<div class="versionadded">
<p><span class="versionmodified added">Added in version 3.14.</span></p>
</div>
</dd></dl>
</section>
</section>
<section id="legacy-locking-apis">
<h2>Legacy locking APIs<a class="headerlink" href="#legacy-locking-apis" title="Link to this heading">¶</a></h2>
<p>These APIs are obsolete since Python 3.13 with the introduction of
<a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a>.</p>
<div class="versionchanged">
<p><span class="versionmodified changed">Changed in version 3.15: </span>These APIs are now a simple wrapper around <code class="docutils literal notranslate"><span class="pre">PyMutex</span></code>.</p>
</div>
<dl class="c type">
<dt class="sig sig-object c" id="c.PyThread_type_lock">
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_type_lock</span></span></span><a class="headerlink" href="#c.PyThread_type_lock" title="Link to this definition">¶</a><br /></dt>
<dd><p>A pointer to a mutual exclusion lock.</p>
</dd></dl>
<dl class="c type">
<dt class="sig sig-object c" id="c.PyLockStatus">
<span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyLockStatus</span></span></span><a class="headerlink" href="#c.PyLockStatus" title="Link to this definition">¶</a><br /></dt>
<dd><p>The result of acquiring a lock with a timeout.</p>
<dl class="c enumerator">
<dt class="sig sig-object c" id="c.PY_LOCK_FAILURE">
<span class="k"><span class="pre">enumerator</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PY_LOCK_FAILURE</span></span></span><a class="headerlink" href="#c.PY_LOCK_FAILURE" title="Link to this definition">¶</a><br /></dt>
<dd><p>Failed to acquire the lock.</p>
</dd></dl>
<dl class="c enumerator">
<dt class="sig sig-object c" id="c.PY_LOCK_ACQUIRED">
<span class="k"><span class="pre">enumerator</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PY_LOCK_ACQUIRED</span></span></span><a class="headerlink" href="#c.PY_LOCK_ACQUIRED" title="Link to this definition">¶</a><br /></dt>
<dd><p>The lock was successfully acquired.</p>
</dd></dl>
<dl class="c enumerator">
<dt class="sig sig-object c" id="c.PY_LOCK_INTR">
<span class="k"><span class="pre">enumerator</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PY_LOCK_INTR</span></span></span><a class="headerlink" href="#c.PY_LOCK_INTR" title="Link to this definition">¶</a><br /></dt>
<dd><p>The lock was interrupted by a signal.</p>
</dd></dl>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyThread_allocate_lock">
<a class="reference internal" href="#c.PyThread_type_lock" title="PyThread_type_lock"><span class="n"><span class="pre">PyThread_type_lock</span></span></a><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_allocate_lock</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.PyThread_allocate_lock" 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>Allocate a new lock.</p>
<p>On success, this function returns a lock; on failure, this
function returns <code class="docutils literal notranslate"><span class="pre">0</span></code> without an exception set.</p>
<p>The caller does not need to hold 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="versionchanged">
<p><span class="versionmodified changed">Changed in version 3.15: </span>This function now always uses <a class="reference internal" href="#c.PyMutex" title="PyMutex"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMutex</span></code></a>. In prior versions, this
would use a lock provided by the operating system.</p>
</div>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyThread_free_lock">
<span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_free_lock</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThread_type_lock" title="PyThread_type_lock"><span class="n"><span class="pre">PyThread_type_lock</span></span></a><span class="w"> </span><span class="n"><span class="pre">lock</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_free_lock" 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 <em>lock</em>. The lock should not be held by any thread when calling
this.</p>
<p>The caller does not need to hold an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</p>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyThread_acquire_lock_timed">
<a class="reference internal" href="#c.PyLockStatus" title="PyLockStatus"><span class="n"><span class="pre">PyLockStatus</span></span></a><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_acquire_lock_timed</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThread_type_lock" title="PyThread_type_lock"><span class="n"><span class="pre">PyThread_type_lock</span></span></a><span class="w"> </span><span class="n"><span class="pre">lock</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">microseconds</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">intr_flag</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_acquire_lock_timed" 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>Acquire <em>lock</em> with a timeout.</p>
<p>This will wait for <em>microseconds</em> microseconds to acquire the lock. If the
timeout expires, this function returns <a class="reference internal" href="#c.PY_LOCK_FAILURE" title="PY_LOCK_FAILURE"><code class="xref c c-enumerator docutils literal notranslate"><span class="pre">PY_LOCK_FAILURE</span></code></a>.
If <em>microseconds</em> is <code class="docutils literal notranslate"><span class="pre">-1</span></code>, this will wait indefinitely until the lock has
been released.</p>
<p>If <em>intr_flag</em> is <code class="docutils literal notranslate"><span class="pre">1</span></code>, acquiring the lock may be interrupted by a signal,
in which case this function returns <a class="reference internal" href="#c.PY_LOCK_INTR" title="PY_LOCK_INTR"><code class="xref c c-enumerator docutils literal notranslate"><span class="pre">PY_LOCK_INTR</span></code></a>. Upon
interruption, it’s generally expected that the caller makes a call to
<a class="reference internal" href="threads.html#c.Py_MakePendingCalls" title="Py_MakePendingCalls"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_MakePendingCalls()</span></code></a> to propagate an exception to Python code.</p>
<p>If the lock is successfully acquired, this function returns
<a class="reference internal" href="#c.PY_LOCK_ACQUIRED" title="PY_LOCK_ACQUIRED"><code class="xref c c-enumerator docutils literal notranslate"><span class="pre">PY_LOCK_ACQUIRED</span></code></a>.</p>
<p>The caller does not need to hold an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</p>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyThread_acquire_lock">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_acquire_lock</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThread_type_lock" title="PyThread_type_lock"><span class="n"><span class="pre">PyThread_type_lock</span></span></a><span class="w"> </span><span class="n"><span class="pre">lock</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">waitflag</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_acquire_lock" 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>Acquire <em>lock</em>.</p>
<p>If <em>waitflag</em> is <code class="docutils literal notranslate"><span class="pre">1</span></code> and another thread currently holds the lock, this
function will wait until the lock can be acquired and will always return
<code class="docutils literal notranslate"><span class="pre">1</span></code>.</p>
<p>If <em>waitflag</em> is <code class="docutils literal notranslate"><span class="pre">0</span></code> and another thread holds the lock, this function will
not wait and instead return <code class="docutils literal notranslate"><span class="pre">0</span></code>. If the lock is not held by any other
thread, then this function will acquire it and return <code class="docutils literal notranslate"><span class="pre">1</span></code>.</p>
<p>Unlike <a class="reference internal" href="#c.PyThread_acquire_lock_timed" title="PyThread_acquire_lock_timed"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyThread_acquire_lock_timed()</span></code></a>, acquiring the lock cannot be
interrupted by a signal.</p>
<p>The caller does not need to hold an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</p>
</dd></dl>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyThread_release_lock">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">PyThread_release_lock</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.PyThread_type_lock" title="PyThread_type_lock"><span class="n"><span class="pre">PyThread_type_lock</span></span></a><span class="w"> </span><span class="n"><span class="pre">lock</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyThread_release_lock" 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>Release <em>lock</em>. If <em>lock</em> is not held, then this function issues a
fatal error.</p>
<p>The caller does not need to hold an <a class="reference internal" href="../glossary.html#term-attached-thread-state"><span class="xref std std-term">attached thread state</span></a>.</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="#">Synchronization primitives</a><ul>
<li><a class="reference internal" href="#python-critical-section-api">Python critical section API</a><ul>
<li><a class="reference internal" href="#low-level-critical-section-api">Low-level critical section API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#legacy-locking-apis">Legacy locking APIs</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="threads.html"
title="previous chapter">Thread states and the global interpreter lock</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="tls.html"
title="next chapter">Thread-local storage support</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/synchronization.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/main/Doc/c-api/synchronization.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="tls.html" title="Thread-local storage support"
>next</a> |</li>
<li class="right" >
<a href="threads.html" title="Thread states and the global interpreter lock"
>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> »</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.0rc1 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="">Synchronization primitives</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 Aug 04, 2026 (11:13 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>