Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Docs: C API: Improve documentation around non-Python threads with subinterpreters#131087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
Document some examples and notes about non-Python threads with subint…
…erpreters.
  • Loading branch information
@ZeroIntensity
ZeroIntensity committedMar 11, 2025
commit1b10658f7640abe330f9e8bf5673a0a29e7ecdc8
54 changes: 48 additions & 6 deletionsDoc/c-api/init.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1064,8 +1064,37 @@ Note that the ``PyGILState_*`` functions assume there is only one global
interpreter (created automatically by :c:func:`Py_Initialize`). Python
supports the creation of additional interpreters (using
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
``PyGILState_*`` API is unsupported.
``PyGILState_*`` API is unsupported. This is because :c:func:`PyGILState_Ensure`
and similar functions almost always acquire the :term:`GIL` of the main interpreter
in threads created by subinterpreters, which can lead to data races or deadlocks.

Supporting subinterpreters in non-Python threads
------------------------------------------------

If you would like to support subinterpreters with non-Python created threads, you
must use the ``PyThreadState_*`` API instead of the traditional ``PyGILState_*``
API.

In particular, you must store the exact interpreter state from the calling
function and pass it to :c:func:`PyThreadState_New` to ensure that the thread
acquires the :term:`GIL` of the subinterpreter instead of the main interpreter.
In turn, this means that the return value of :c:func:`PyInterpreterState_Get`
should be stored alongside any information passed to the thread.::

/* The return value of PyInterpreterState_Get() from the
function that created this thread. */
PyInterpreterState *interp = ThreadData->interp;
PyThreadState *tstate = PyThreadState_New(interp);
PyThreadState_Swap(tstate);

/* GIL of the subinterpreter is now held.
Perform Python actions here. */
result = CallSomeFunction();
/* evaluate result or handle exception */

/* Destroy the thread state. No Python API allowed beyond this point. */
PyThreadState_Clear(tstate);
PyThreadState_DeleteCurrent();

.. _fork-and-threads:

Expand DownExpand Up@@ -1243,6 +1272,10 @@ code, or when embedding the Python interpreter:
*tstate*, which may be ``NULL``. The global interpreter lock must be held
and is not released.

.. note::
Similar to :c:func:`PyGILState_Ensure`, this function will hang the
thread if the runtime is finalizing.


The following functions use thread-local storage, and are not compatible
with sub-interpreters:
Expand All@@ -1269,10 +1302,10 @@ with sub-interpreters:
When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.

..note::
Calling this functionfrom a threadwhen the runtime is finalizingwill
hang the thread until the programexits, even if the thread was not
created by Python. Refer to
..warning::
Calling this function when the runtime is finalizingis unsafe. Doing
so will eitherhang the thread until the programends, or fully crash
the interpreter in rare cases. Refer to
:ref:`cautions-regarding-runtime-finalization` for more details.

.. versionchanged:: 3.14
Expand All@@ -1289,14 +1322,18 @@ with sub-interpreters:
Every call to :c:func:`PyGILState_Ensure` must be matched by a call to
:c:func:`PyGILState_Release` on the same thread.


.. c:function:: PyThreadState* PyGILState_GetThisThreadState()

Get the current thread state for this thread. May return ``NULL`` if no
GILState API has been used on the current thread. Note that the main thread
always has such a thread-state, even if no auto-thread-state call has been
made on the main thread. This is mainly a helper/diagnostic function.

.. note::
This function does not account for thread states created by something
other than :c:func:`PyGILState_Ensure` (such as :c:func:`PyThreadState_New`).
Prefer :c:func:`PyThreadState_Get` or :c:func:`PyThreadState_GetUnchecked`
for most cases.

.. c:function:: int PyGILState_Check()

Expand All@@ -1309,6 +1346,11 @@ with sub-interpreters:
knowing that the GIL is locked can allow the caller to perform sensitive
actions or otherwise behave differently.

.. note::
If the current Python process has ever created a subinterpreter, this
function will *always* return ``1``. Prefer :c:func:`PyThreadState_GetUnchecked`
for most cases.

.. versionadded:: 3.4


Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp