Skip to content

Commit 9f1307a

Browse files
miss-islingtonZeroIntensityvstinner
authored
[3.14] Docs: C API: Improve documentation around non-Python threads with subinterpreters (GH-131087) (GH-134130)
Docs: C API: Improve documentation around non-Python threads with subinterpreters (GH-131087) (cherry picked from commit af6b3b8) Co-authored-by: Peter Bierma <[email protected]> Co-authored-by: Victor Stinner <[email protected]>
1 parent 851b26f commit 9f1307a

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

Doc/c-api/init.rst

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,8 +1083,36 @@ Note that the ``PyGILState_*`` functions assume there is only one global
10831083
interpreter (created automatically by :c:func:`Py_Initialize`). Python
10841084
supports the creation of additional interpreters (using
10851085
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
1086-
``PyGILState_*`` API is unsupported.
1086+
``PyGILState_*`` API is unsupported. This is because :c:func:`PyGILState_Ensure`
1087+
and similar functions default to :term:`attaching <attached thread state>` a
1088+
:term:`thread state` for the main interpreter, meaning that the thread can't safely
1089+
interact with the calling subinterpreter.
1090+
1091+
Supporting subinterpreters in non-Python threads
1092+
------------------------------------------------
1093+
1094+
If you would like to support subinterpreters with non-Python created threads, you
1095+
must use the ``PyThreadState_*`` API instead of the traditional ``PyGILState_*``
1096+
API.
1097+
1098+
In particular, you must store the interpreter state from the calling
1099+
function and pass it to :c:func:`PyThreadState_New`, which will ensure that
1100+
the :term:`thread state` is targeting the correct interpreter::
1101+
1102+
/* The return value of PyInterpreterState_Get() from the
1103+
function that created this thread. */
1104+
PyInterpreterState *interp = ThreadData->interp;
1105+
PyThreadState *tstate = PyThreadState_New(interp);
1106+
PyThreadState_Swap(tstate);
1107+
1108+
/* GIL of the subinterpreter is now held.
1109+
Perform Python actions here. */
1110+
result = CallSomeFunction();
1111+
/* evaluate result or handle exception */
10871112
1113+
/* Destroy the thread state. No Python API allowed beyond this point. */
1114+
PyThreadState_Clear(tstate);
1115+
PyThreadState_DeleteCurrent();
10881116
10891117
.. _fork-and-threads:
10901118
@@ -1261,6 +1289,10 @@ code, or when embedding the Python interpreter:
12611289
.. seealso:
12621290
:c:func:`PyEval_ReleaseThread`
12631291
1292+
.. note::
1293+
Similar to :c:func:`PyGILState_Ensure`, this function will hang the
1294+
thread if the runtime is finalizing.
1295+
12641296
12651297
The following functions use thread-local storage, and are not compatible
12661298
with sub-interpreters:
@@ -1287,10 +1319,10 @@ with sub-interpreters:
12871319
When the function returns, there will be an :term:`attached thread state`
12881320
and the thread will be able to call arbitrary Python code. Failure is a fatal error.
12891321
1290-
.. note::
1291-
Calling this function from a thread when the runtime is finalizing will
1292-
hang the thread until the program exits, even if the thread was not
1293-
created by Python. Refer to
1322+
.. warning::
1323+
Calling this function when the runtime is finalizing is unsafe. Doing
1324+
so will either hang the thread until the program ends, or fully crash
1325+
the interpreter in rare cases. Refer to
12941326
:ref:`cautions-regarding-runtime-finalization` for more details.
12951327
12961328
.. versionchanged:: 3.14
@@ -1307,28 +1339,37 @@ with sub-interpreters:
13071339
Every call to :c:func:`PyGILState_Ensure` must be matched by a call to
13081340
:c:func:`PyGILState_Release` on the same thread.
13091341
1310-
13111342
.. c:function:: PyThreadState* PyGILState_GetThisThreadState()
13121343
13131344
Get the :term:`attached thread state` for this thread. May return ``NULL`` if no
13141345
GILState API has been used on the current thread. Note that the main thread
13151346
always has such a thread-state, even if no auto-thread-state call has been
13161347
made on the main thread. This is mainly a helper/diagnostic function.
13171348
1318-
.. seealso: :c:func:`PyThreadState_Get``
1349+
.. note::
1350+
This function does not account for :term:`thread states <thread state>` created
1351+
by something other than :c:func:`PyGILState_Ensure` (such as :c:func:`PyThreadState_New`).
1352+
Prefer :c:func:`PyThreadState_Get` or :c:func:`PyThreadState_GetUnchecked`
1353+
for most cases.
13191354
1355+
.. seealso: :c:func:`PyThreadState_Get``
13201356
13211357
.. c:function:: int PyGILState_Check()
13221358
13231359
Return ``1`` if the current thread is holding the :term:`GIL` and ``0`` otherwise.
13241360
This function can be called from any thread at any time.
1325-
Only if it has had its Python thread state initialized and currently is
1326-
holding the :term:`GIL` will it return ``1``.
1361+
Only if it has had its :term:`thread state <attached thread state>` initialized
1362+
via :c:func:`PyGILState_Ensure` will it return ``1``.
13271363
This is mainly a helper/diagnostic function. It can be useful
13281364
for example in callback contexts or memory allocation functions when
13291365
knowing that the :term:`GIL` is locked can allow the caller to perform sensitive
13301366
actions or otherwise behave differently.
13311367
1368+
.. note::
1369+
If the current Python process has ever created a subinterpreter, this
1370+
function will *always* return ``1``. Prefer :c:func:`PyThreadState_GetUnchecked`
1371+
for most cases.
1372+
13321373
.. versionadded:: 3.4
13331374
13341375

0 commit comments

Comments
 (0)