@@ -1018,13 +1018,23 @@ The block above expands to the following code::
10181018 single: PyEval_RestoreThread (C function)
10191019 single: PyEval_SaveThread (C function)
10201020
1021- Here is how these functions work: the global interpreter lock is used to protect the pointer to the
1022- current :term:`thread state`. When releasing the lock and saving the :term:`thread state`,
1023- the current thread state pointer must be retrieved before the lock is released
1024- (since another thread could immediately acquire the lock and store its own :term:`thread
1025- state` in the global variable). Conversely, when acquiring the lock and restoring
1026- the :term:`thread state`, the lock must be acquired before storing the :term:`thread state``
1027- pointer.
1021+ Here is how these functions work:
1022+
1023+ The :term:`thread state` holds the :term:`GIL` for the entire interpreter. When detaching
1024+ the :term:`thread state`, the :term:`GIL` is released, allowing other threads to attach
1025+ their own :term:`thread state`, thus getting the :term:`GIL` and can start executing.
1026+ The pointer to the now-detached :term:`thread state`` is stored as a local variable.
1027+ Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the :term:`thread state` that was
1028+ previously attached is given to :c:func:`PyEval_RestoreThread`. This function will
1029+ block until another thread that the :term:`GIL` can be re-acquired, thus allowing
1030+ the :term:`thread state` to get re-attached and the C API can be called again.
1031+
1032+ For :term:`free-threaded <free-threading>` builds, the :term:`GIL` is normally
1033+ out of the question, but detaching the thread state is still required for blocking I/O
1034+ and long operations. The difference is that threads don't have to wait for the :term:`GIL`
1035+ to be released to attach their thread state, allowing true multi-core parallelism.
1036+
1037+ :c:func:`PyEval_SaveThread`
10281038
10291039.. note::
10301040 Calling system I/O functions is the most common use case for detaching
@@ -1044,16 +1054,15 @@ When threads are created using the dedicated Python APIs (such as the
10441054:mod:`threading` module), a thread state is automatically associated to them
10451055and the code showed above is therefore correct. However, when threads are
10461056created from C (for example by a third-party library with its own thread
1047- management), they don't hold the GIL, nor is there a thread state structure
1048- for them .
1057+ management), they don't hold the :term:` GIL`, because they don't have a
1058+ :term:`thread state` .
10491059
10501060If you need to call Python code from these threads (often this will be part
10511061of a callback API provided by the aforementioned third-party library),
10521062you must first register these threads with the interpreter by
1053- creating a thread state data structure, then acquiring the GIL, and finally
1054- storing their thread state pointer, before you can start using the Python/C
1055- API. When you are done, you should reset the thread state pointer, release
1056- the GIL, and finally free the thread state data structure.
1063+ creating a :term:`thread state` before you can start using the Python/C
1064+ API. When you are done, you should detach the :term:`thread state`, and
1065+ finally free it.
10571066
10581067The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do
10591068all of the above automatically. The typical idiom for calling into Python
@@ -1126,21 +1135,19 @@ is marked as *finalizing*: :c:func:`_Py_IsFinalizing` and
11261135thread* that initiated finalization (typically the main thread) is allowed to
11271136acquire the :term:`GIL`.
11281137
1129- If any thread, other than the finalization thread, attempts to acquire the GIL
1130- during finalization, either explicitly via :c:func:`PyGILState_Ensure`,
1131- :c:macro:`Py_END_ALLOW_THREADS`, :c:func:`PyEval_AcquireThread`, or
1132- :c:func:`PyEval_AcquireLock`, or implicitly when the interpreter attempts to
1133- reacquire it after having yielded it, the thread enters **a permanently blocked
1134- state** where it remains until the program exits. In most cases this is
1135- harmless, but this can result in deadlock if a later stage of finalization
1136- attempts to acquire a lock owned by the blocked thread, or otherwise waits on
1137- the blocked thread.
1138+ If any thread, other than the finalization thread, attempts to attach a :term:`thread state`
1139+ during finalization, either explicitly via a :term:`thread state` function, or
1140+ implicitly when the interpreter attempts yields the :term:`GIL` by detaching the
1141+ :term:`thread state`, the thread enters **a permanently blocked state** where it
1142+ remains until the program exits. In most cases this is harmless, but this can result
1143+ in deadlock if a later stage of finalization attempts to acquire a lock owned by the
1144+ blocked thread, or otherwise waits on the blocked thread.
11381145
11391146Gross? Yes. This prevents random crashes and/or unexpectedly skipped C++
11401147finalizations further up the call stack when such threads were forcibly exited
1141- here in CPython 3.13 and earlier. The CPython runtime GIL acquiring C APIs
1142- have never had any error reporting or handling expectations at GIL acquisition
1143- time that would've allowed for graceful exit from this situation. Changing that
1148+ here in CPython 3.13 and earlier. The CPython runtime :term:`thread state` C APIs
1149+ have never had any error reporting or handling expectations at :term:`thread state`
1150+ attachment time that would've allowed for graceful exit from this situation. Changing that
11441151would require new stable C APIs and rewriting the majority of C code in the
11451152CPython ecosystem to use those with error handling.
11461153
0 commit comments