/
shapovalovav
/
AI-Agent
Обзор
Документация
Войти
/
shapovalovav
/
AI-Agent
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Python314/Doc/html/c-api/synchronization.html
665 строк
46 KB
Anatoly1147
first_commit
11 июл 2026, 17:02
11 июл 2026, 17:02
f6c78bd
Код
Авторство
О чём код?
<!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.14.4 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=82640b3f" /> <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=1885ab2e"></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.4 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></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.14.4 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-shared"> Thread safety: <a class="reference internal" href="../library/threadsafety.html#threadsafety-level-shared"><span class="std std-ref">Safe for concurrent use on the same object</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-shared"> Thread safety: <a class="reference internal" href="../library/threadsafety.html#threadsafety-level-shared"><span class="std std-ref">Safe for concurrent use on the same object</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> <p>The functions and structs used by the macros are exposed for cases where C macros are not available. They should only be used as in the given macro expansions. Note that the sizes and contents of the structures may change in future Python versions.</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"> <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><p>Acquires the per-object lock for the object <em>op</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_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><p>Ends the critical section and releases the per-object lock.</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="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><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, 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><p>Ends the critical section and releases the per-object locks.</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="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> <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> <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> </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></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.14.4 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 Apr 07, 2026 (13:52 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>