8000 gh-127989: C API: Refer to attached thread states instead of the GIL by ZeroIntensity · Pull Request #127990 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-127989: C API: Refer to attached thread states instead of the GIL #127990

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 76 commits into from
Mar 20, 2025
Merged
Changes from 1 commit
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
ad7ee2d
Document the term 'thread state.'
ZeroIntensity Dec 14, 2024
bea045a
Change term for PyDict_GetItem
ZeroIntensity Dec 14, 2024
e286ba5
Change term for PyErr_Occurred
ZeroIntensity Dec 14, 2024
6006b22
Change term for PyErr_SetInterrupt
ZeroIntensity Dec 14, 2024
8dc3928
Change term for PyErr_SetInterruptEx
ZeroIntensity Dec 14, 2024
f46ca3d
Change term for PyConfig_Get
ZeroIntensity Dec 14, 2024
555a03c
Change term for PyConfig_Names
ZeroIntensity Dec 14, 2024
ddb98cd
Change term for PyConfig_Set
ZeroIntensity Dec 14, 2024
5d423f8
Change term for PyUnstable_AtExit
ZeroIntensity Dec 14, 2024
d2d2f67
Change term for Py_Initialize note
ZeroIntensity Dec 14, 2024
aa9c4c6
Change term for PyInterpreterState_Get
ZeroIntensity Dec 14, 2024
c05be67
Change term for PyInterpreterState_GetID
ZeroIntensity Dec 14, 2024
3a69922
Change term for PyThreadState_SetAsyncEx
ZeroIntensity Dec 14, 2024
3336ad7
Change term for Py_NewInterpreterFromConfig
ZeroIntensity Dec 14, 2024
3991681
Change term for Py_FinalizeEx
ZeroIntensity Dec 14, 2024
6d397eb
Change term for Py_AddPendingCall
ZeroIntensity Dec 14, 2024
3b7b3ff
Change term for PyEval_SetProfile
ZeroIntensity Dec 14, 2024
5358d14
Change term for PyEval_SetProfileAllThreads
ZeroIntensity Dec 14, 2024
093ba05
Change term for PyEval_SetTrace
ZeroIntensity Dec 14, 2024
11582fa
Change term 8000 for PyEval_SetTraceAllThreads
ZeroIntensity Dec 14, 2024
3d55d2d
Change term for PyRefTracer_SetTracer
ZeroIntensity Dec 14, 2024
2785c1d
Change term for PyRefTracer_GetTracer
ZeroIntensity Dec 14, 2024
6d80b02
Change term for PyMutex_Lock
ZeroIntensity Dec 14, 2024
94e046b
Change term for allocator domains
ZeroIntensity Dec 14, 2024
713beb2
Change term for raw memory interface
ZeroIntensity Dec 14, 2024
2140bde
Change term for memory interface
ZeroIntensity Dec 14, 2024
f608211
Change term for object allocators
ZeroIntensity Dec 14, 2024
d619387
Change term for PyMem_SetAllocator
ZeroIntensity Dec 14, 2024
e7828ed
Change term for PyMem_SetAllocator (again)
ZeroIntensity Dec 14, 2024
6b33565
Change term for debug hooks
ZeroIntensity Dec 14, 2024
6230177
Change term for debug hooks (again)
ZeroIntensity Dec 14, 2024
f74832a
Change term for PyState*
ZeroIntensity Dec 14, 2024
7161fc0
Change term for various things
ZeroIntensity Dec 14, 2024
d58b74f
Change term for clock functions
ZeroIntensity Dec 14, 2024
a761c4a
Change term for raw clock functions
ZeroIntensity Dec 14, 2024
de122f5
Change term for tp_dealloc warning
ZeroIntensity Dec 14, 2024
0b0176b
Change term for the types tutorial
ZeroIntensity Dec 14, 2024
c15f5c4
Add more information about thread states.
ZeroIntensity Dec 14, 2024
0130b20
Change terms for 'cautions regarding runtime finalization'
ZeroIntensity Dec 14, 2024
a1e47b7
Simplify PyEval_SaveThread and PyEval_RestoreThread
ZeroIntensity Dec 14, 2024
0173c46
Some more terminology fixups.
ZeroIntensity Dec 14, 2024
166d970
Fix Sphinx build errors.
ZeroIntensity Dec 14, 2024
adae494
Change some usage of the term 'global interpreter lock'
ZeroIntensity Dec 14, 2024
a70ab11
Add some more terms for disambiguation.
ZeroIntensity Dec 14, 2024
8584c86
Change usage of some terms.
ZeroIntensity Dec 14, 2024
48b145a
Play around with terminology.
ZeroIntensity Dec 14, 2024
8ce3d7d
Various terminology changes.
ZeroIntensity Dec 14, 2024
e5f1d18
Change the glossary definition a little bit.
ZeroIntensity Dec 14, 2024
905ca5b
Change some phrasing.
ZeroIntensity Dec 14, 2024
f2826c4
Fix some usage of terms.
ZeroIntensity Dec 14, 2024
5c44391
Change some usage of 'global interpreter lock'
ZeroIntensity Dec 15, 2024
7d5877f
Fix pre-commit lint.
ZeroIntensity Dec 15, 2024
283fc92
Delete redundant file
ZeroIntensity Dec 16, 2024
a7488ab
Revert "Delete redundant file"
ZeroIntensity Dec 16, 2024
4c532b6
Remove accidental find-and-replace change.
ZeroIntensity Dec 16, 2024
352acc5
Switch to a reference
ZeroIntensity Dec 16, 2024
ed550bc
Use a less wordy phrase for detaching.
ZeroIntensity Dec 16, 2024
d7cf403
Fix a typo in PyInterpreterState_Get
ZeroIntensity Dec 16, 2024
f61a6da
Change some wording in PyEval_SaveThread and PyEval_RestoreThread
ZeroIntensity Dec 16, 2024
36af941
Change wording for PyThreadState_Swap
ZeroIntensity Dec 16, 2024
0b23daa
Make glossary terms more clear.
ZeroIntensity Dec 16, 2024
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
Prev Previous commit
Next Next commit
Change usage of some terms.
  • Loading branch information
ZeroIntensity committed Dec 14, 2024
commit 8584c867a1fe75c7a890adac8ad9dbdf121d2c74
44 changes: 22 additions & 22 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -966,18 +966,17 @@ inside a data structure called :c:type:`PyThreadState`, known as a :term:`thread
There's also one thread-local variable pointing to the current :c:type:`PyThreadState`: it can
be retrieved using :c:func:`PyThreadState_Get`.

A thread can only have one attached :term:`thread state` at a time. An attached
:term:`thread state` is typically analogous with holding the :term:`GIL`, except on
A thread can only have one :term:`attached thread state` at a time. An attached
thread state is typically analogous with holding the :term:`GIL`, except on
:term:`free-threaded <free threading>` builds. On builds with the :term:`GIL` enabled,
attaching a thread state will block until the :term:`GIL` can be acquired.
However, even on builds with the :term:`GIL` disabled, it is still required
to have a :term:`thread state` attached to the current thread to call most of
to have a thread state attached to the current thread to call most of
the C API.

In general, a :term:`thread state` will always be active for the current thread
when using Python's C API. Only in some specific cases (such as in a
:c:macro:`Py_BEGIN_ALLOW_THREADS` block) will the thread not have an active
thread state. If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns
In general, there will always be an :term:`attached thread state` when using Python's C API.
Only in some specific cases (such as in a :c:macro:`Py_BEGIN_ALLOW_THREADS` block) will the
thread not have an attached thread state. If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns
``NULL``.

Detaching the thread state from extension code
Expand Down Expand Up @@ -1018,14 +1017,15 @@ The block above expands to the following code::

Here is how these functions work:

The :term:`thread state` holds the :term:`GIL` for the entire interpreter. When detaching
the :term:`thread state`, the :term:`GIL` is released, allowing other threads to attach
their own :term:`thread state`, thus getting the :term:`GIL` and can start executing.
The pointer to the now-detached :term:`thread state` is stored as a local variable.
Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the :term:`thread state` that was
previously attached is given to :c:func:`PyEval_RestoreThread`. This function will
block until another thread that the :term:`GIL` can be re-acquired, thus allowing
the :term:`thread state` to get re-attached and the C API can be called again.
The :term:`attached thread state` holds the :term:`GIL` for the entire interpreter. When detaching
the :term:`attached thread state`, the :term:`GIL` is released, allowing other threads to attach
a thread state to their own thread, thus getting the :term:`GIL` and can start executing.
The pointer to the prior :term:`attached thread state` is stored as a local variable.
Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the thread state that was
previously :term:`attached <attached thread state>` is passed to :c:func:`PyEval_RestoreThread`.
This function will block until another releases its :term:`thread state <attached thread state>`,
thus allowing the old :term:`thread state <attached thread state>` to get re-attached and the
C API can be called again.

For :term:`free-threaded <free threading>` builds, the :term:`GIL` is normally
out of the question, but detaching the thread state is still required for blocking I/O
Expand All @@ -1038,7 +1038,7 @@ to be released to attach their thread state, allowing true multi-core parallelis
long-running computations which don't need access to Python objects, such
as compression or cryptographic functions operating over memory buffers.
For example, the standard :mod:`zlib` and :mod:`hashlib` modules detach the
:term:`thread state` when compressing or hashing data.
:term:`attached thread state` when compressing or hashing data.


.. _gilstate:
Expand All @@ -1050,14 +1050,14 @@ When threads are created using the dedicated Python APIs (such as the
:mod:`threading` module), a thread state is automatically associated to them
and the code showed above is therefore correct. However, when threads are
created from C (for example by a third-party library with its own thread
management), they don't hold the :term:`GIL`, because they don't have a
:term:`thread state`.
management), they don't hold the :term:`GIL`, because they don't have an
:term:`attached thread state`.

If you need to call Python code from these threads (often this will be part
of a callback API provided by the aforementioned third-party library),
you must first register these threads with the interpreter by
creating a :term:`thread state` before you can start using the Python/C
API. When you are done, you should detach the :term:`thread state`, and
creating an :term:`attached thread state` before you can start using the Python/C
API. When you are done, you should detach the :term:`thread state <attached thread state>`, and
finally free it.

The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do
Expand Down Expand Up @@ -1134,8 +1134,8 @@ acquire the :term:`GIL`.
If any thread, other than the finalization thread, attempts to attach a :term:`thread state`
during finalization, either explicitly via a :term:`thread state` function, or
implicitly when the interpreter attempts yields the :term:`GIL` by detaching the
:term:`thread state`, the thread enters **a permanently blocked state** where it
remains until the program exits. In most cases this is harmless, but this can result
:term:`thread state <attached thread state>`, the thread enters **a permanently blocked state**
where it remains until the program exits. In most cases this is harmless, but this can result
in deadlock if a later stage of finalization attempts to acquire a lock owned by the
blocked thread, or otherwise waits on the blocked thread.

Expand Down
0