8000 PEP 788: Minor clarity changes and improvements (#4474) · python/peps@f5e2ca9 · GitHub
[go: up one dir, main page]

Skip to content

Commit f5e2ca9

Browse files
PEP 788: Minor clarity changes and improvements (#4474)
* Remove the 10-year deprecation. * Many clarity fixes. * Add an 'Acknowledgements' section. * Remove 'Open Issues' section.
1 parent 83ccbaa commit f5e2ca9

File tree

1 file changed

+101
-93
lines changed

1 file changed

+101
-93
lines changed

peps/pep-0788.rst

Lines changed: 101 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ of a Python process.
6262

6363
The "current interpreter" refers to the interpreter-state
6464
pointer on an :term:`attached thread state`, as returned by
65-
:c:func:`PyThreadState_GetInterpreter`.
65+
:c:func:`PyThreadState_GetInterpreter` or :c:func:`PyInterpreterState_Get`.
6666

6767
Native and Python Threads
6868
-------------------------
@@ -162,8 +162,17 @@ This affects CPython itself, and there's not much that can be done
162162
to fix it with the current API. For example,
163163
`python/cpython#129536 <https://github.com/python/cpython/issues/129536>`_
164164
remarks that the :mod:`ssl` module can emit a fatal error when used at
165-
finalization, because a daemon thread got hung while holding the lock.
166-
165+
finalization, because a daemon thread got hung while holding the lock
166+
for :data:`sys.stderr`, and then a finalizer tried to write to it.
167+
Ideally, a thread should be able to temporarily prevent the interpreter
168+
from hanging it while it holds the lock.
169+
170+
However, it's generally unsafe to acquire Python locks (for example,
171+
:class:`threading.Lock`) in finalizers, because the garbage collector
172+
might run while the lock is held, which would deadlock if another finalizer
173+
tried to acquire the lock. This does not apply to many C locks, such as with
174+
:data:`sys.stderr`, because Python code cannot be run while the lock is held.
175+
This PEP intends to fix this problem for C locks, not Python locks.
167176

168177
Daemon Threads are not the Problem
169178
**********************************
@@ -179,9 +188,9 @@ threads is that they're a large cause of problems in the interpreter:
179188
down upon runtime finalization. As in they have pointers to global state for
180189
the interpreter.
181190

182-
In practice, daemon threads are useful for simplifying many threading applications
183-
in Python, and since the program is about to close in most cases, it's not worth
184-
the added complexity to try and gracefully shut down a thread.
191+
However, in practice, daemon threads are useful for simplifying many threading
192+
applications in Python, and since the program is about to close in most cases,
193+
it's not worth the added complexity to try and gracefully shut down a thread.
185194

186195
When I’ve needed daemon threads, it’s usually been the case of “Long-running,
187196
uninterruptible, third-party task” in terms of the examples in the linked issue.
@@ -196,7 +205,7 @@ As noted by this PEP, extension modules are free to create their own threads
196205
and attach thread states for them. Similar to daemon threads, Python doesn't
197206
try and join them during finalization, so trying to remove daemon threads
198207
as a whole would involve trying to remove them from the C API, which would
199-
require a massive API change.
208+
require a much more massive API change.
200209

201210
Realize however that even if we get rid of daemon threads, extension
202211
module code can and does spawn its own threads that are not tracked by
@@ -216,7 +225,7 @@ needs to already have an :term:`attached thread state` for the thread. If
216225
there's no guarantee of that, then :func:`atexit.register` cannot be safely
217226
called without the risk of hanging the thread. This shifts the contract
218227
of joining the thread to the caller rather than the callee, which again,
219-
isn't done in practice.
228+
isn't reliable enough in practice to be a viable solution.
220229

221230
For example, large C++ applications might want to expose an interface that can
222231
call Python code. To do this, a C++ API would take a Python object, and then
@@ -252,8 +261,12 @@ The GIL-state APIs are Buggy and Confusing
252261

253262
There are currently two public ways for a user to create and attach a
254263
:term:`thread state` for their thread; manual use of :c:func:`PyThreadState_New`
255-
and :c:func:`PyThreadState_Swap`, and :c:func:`PyGILState_Ensure`. The latter,
256-
:c:func:`PyGILState_Ensure`, is `the most common <https://grep.app/search?q=pygilstate_ensure>`_.
264+
and :c:func:`PyThreadState_Swap`, or the convenient :c:func:`PyGILState_Ensure`.
265+
266+
The latter, :c:func:`PyGILState_Ensure`, is significantly more common, having
267+
`nearly 3,000 hits <https://grep.app/search?q=pygilstate_ensure>`_ in a code
268+
search, whereas :c:func:`PyThreadState_New` has
269+
`less than 400 hits <https://grep.app/search?q=PyThreadState_New>`_.
257270

258271
``PyGILState_Ensure`` Generally Crashes During Finalization
259272
***********************************************************
@@ -263,7 +276,7 @@ always match the documentation. Instead of hanging the thread during finalizatio
263276
as previously noted, it's possible for it to crash with a segmentation
264277
fault. This is a `known issue <https://github.com/python/cpython/issues/124619>`_
265278
that could be fixed in CPython, but it's definitely worth noting
266-
here. Incidentally, acceptance and implementation of this PEP will likely fix
279+
here, because acceptance and implementation of this PEP will likely fix
267280
the existing crashes caused by :c:func:`PyGILState_Ensure`.
268281

269282
The Term "GIL" is Tricky for Free-threading
@@ -279,28 +292,7 @@ created by the authors of this PEP:
279292
omit ``PyGILState_Ensure`` in fresh threads.
280293

281294
Again, :c:func:`PyGILState_Ensure` gets an :term:`attached thread state`
282-
for the thread on both with-GIL and free-threaded builds. To demonstate,
283-
:c:func:`PyGILState_Ensure` is very roughly equivalent to the following:
284-
285-
.. code-block:: c
286-
287-
PyGILState_STATE
288-
PyGILState_Ensure(void)
289-
{
290-
PyThreadState *existing = PyThreadState_GetUnchecked();
291-
if (existing == NULL) {
292-
// Chooses the interpreter of the last attached thread state
293-
// for this thread. If Python has never ran in this thread, the
294-
// main interpreter is used.
295-
PyInterpreterState *interp = guess_interpreter();
296-
PyThreadState *tstate = PyThreadState_New(interp);
297-
PyThreadState_Swap(tstate);
298-
return opaque_tstate_handle(tstate);
299-
} else {
300-
return opaque_tstate_handle(existing);
301-
}
302-
}
303-
295+
for the thread on both with-GIL and free-threaded builds.
304296
An attached thread state is always needed to call the C API, so
305297
:c:func:`PyGILState_Ensure` still needs to be called on free-threaded builds,
306298
but with a name like "ensure GIL", it's not immediately clear that that's true.
@@ -331,8 +323,8 @@ subinterpreter, but then called :c:func:`PyGILState_Ensure`, the thread would
331323
have an :term:`attached thread state` pointing to the main interpreter,
332324
not the subinterpreter. This means that any :term:`GIL` assumptions about the
333325
object are wrong! There isn't any synchronization between the two GILs, so both
334-
the thread (who thinks it's in the subinterpreter) and the main thread could try
335-
to increment the reference count at the same time, causing a data race!
326+
the thread and the main thread could try to increment the object's reference count
327+
at the same time, causing a data race.
336328

337329
An Interpreter Can Concurrently Deallocate
338330
------------------------------------------
@@ -342,12 +334,17 @@ The other way of creating a native thread that can invoke Python,
342334
for supporting subinterpreters (because :c:func:`PyThreadState_New` takes an
343335
explicit interpreter, rather than assuming that the main interpreter was
344336
requested), but is still limited by the current hanging problems in the C API.
337+
Manual creation of thread states ("manual" in contrast to the implicit creation
338+
of one in :c:func:`PyGILState_Ensure`) does not solve any of the aforementioned
339+
thread-safety issues with thread states.
345340

346341
In addition, subinterpreters typically have a much shorter lifetime than the
347-
main interpreter, so there's a much higher chance that an interpreter passed
348-
to a thread will have already finished and have been deallocated. So, passing
349-
that interpreter to :c:func:`PyThreadState_New` will most likely crash the program
350-
because of a use-after-free on the interpreter-state.
342+
main interpreter, so if there was no synchronization between the calling thread
343+
and the created thread, there's a much higher chance that an interpreter-state
344+
passed to a thread will have already finished and have been deallocated,
345+
causing use-after-free crashes. As of writing, this is a relatively
346+
theoretical problem, but it's likely this will become more of an issue
347+
in newer versions with the recent acceptance of :pep:`734`.
351348

352349
Rationale
353350
=========
@@ -367,17 +364,30 @@ thread being hung.
367364
This means that interfacing Python (for example, in a C++ library) will need
368365
a reference to the interpreter in order to safely call the object, which is
369366
definitely more inconvenient than assuming the main interpreter is the right
370-
choice, but there's not really another option.
367+
choice, but there's not really another option. A future proposal could perhaps
368+
make this cleaner by adding a tracking mechanism for an object's interpreter
369+
(such as a field on :c:type:`PyObject`).
370+
371+
Generally speaking, a strong interpreter reference should be short-lived. An
372+
interpreter reference should act similar to a lock, or a "critical section",
373+
where the interpreter must not hang the thread or deallocate. For example,
374+
when acquiring an IO lock, a strong interpreter reference should be acquired
375+
before locking, and then released once the lock is released.
371376

372377
Weak References
373378
***************
374379

375380
This proposal also comes with weak references to an interpreter that don't
376381
prevent it from shutting down, but can be promoted to a strong reference when
377-
the user decides that they want to call the C API. Promotion of a weak reference
378-
to a strong reference can fail if the interpreter has already finalized, or
379-
reached a point during finalization where it can't be guaranteed that the
380-
thread won't hang.
382+
the user decides that they want to call the C API. A weak reference will
383+
typically live much longer than a strong reference. This is useful for many of
384+
the asynchronous situations stated previously, where the thread itself
385+
shouldn't prevent the desired interpreter from shutting down, but also allow
386+
the thread to execute Python when needed.
387+
388+
For example, a (non-reentrant) event handler may store a weak interpreter
389+
reference in its ``void *arg`` parameter, and then that weak reference will
390+
be promoted to a strong reference when it's time to call Python code.
381391

382392
Deprecation of the GIL-state APIs
383393
---------------------------------
@@ -389,16 +399,18 @@ subinterpreters:
389399

390400
- :c:func:`PyGILState_Ensure`: :c:func:`PyThreadState_Swap` & :c:func:`PyThreadState_New`
391401
- :c:func:`PyGILState_Release`: :c:func:`PyThreadState_Clear` & :c:func:`PyThreadState_Delete`
392-
- :c:func:`PyGILState_GetThisThreadState`: :c:func:`PyThreadState_Get`
402+
- :c:func:`PyGILState_GetThisThreadState`: :c:func:`PyThreadState_Get` (roughly)
393403
- :c:func:`PyGILState_Check`: ``PyThreadState_GetUnchecked() != NULL``
394404

395-
This PEP specifies a ten-year deprecation for these functions (while remaining
396-
in the stable ABI), mainly because it's expected that the migration will be a
397-
little painful, because :c:func:`PyThreadState_Ensure` and
398-
:c:func:`PyThreadState_Release` aren't drop-in replacements for
405+
This PEP specifies a deprecation for these functions (while remaining
406+
in the stable ABI), because :c:func:`PyThreadState_Ensure` and
407+
:c:func:`PyThreadState_Release` will act as more-correct replacements for
399408
:c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`, due to the
400-
requirement of a specific interpreter. The exact details of this deprecation
401-
aren't too clear, see :ref:`pep-788-deprecation`.
409+
requirement of a specific interpreter.
410+
411+
The exact details of this deprecation aren't too clear. It's likely that
412+
the usual five-year deprecation (as specificed by :pep:`387`) will be too
413+
short, so for now, these functions will have no specific removal date.
402414

403415
Specification
404416
=============
@@ -407,19 +419,22 @@ Interpreter References to Prevent Shutdown
407419
------------------------------------------
408420

409421
An interpreter will keep a reference count that's managed by users of the
410-
C API. When the interpreter starts finalizing, it will until its reference count
411-
reaches zero before proceeding to a point where threads will be hung. This will
412-
happen around the same time when :class:`threading.Thread` objects are joined,
413-
but note that this *is not* the same as joining the thread; the interpreter will
414-
only wait until the reference count is zero, and then proceed. The interpreter
415-
must not hang threads until this reference count has reached zero.
422+
C API. When the interpreter starts finalizing, it will wait until its reference
423+
count reaches zero before proceeding to a point where threads will be hung and
424+
it may deallocate its state. The interpreter will wait on its reference count
425+
around the same time when :class:`threading.Thread` objects are joined, but
426+
note that this *is not* the same as joining the thread; the interpreter will
427+
only wait until the reference count is zero, and then proceed.
416428
After the reference count has reached zero, threads can no longer prevent the
417-
interpreter from shutting down.
429+
interpreter from shutting down (thus :c:func:`PyInterpreterRef_Get` and
430+
:c:func:`PyInterpreterWeakRef_AsStrong` will fail).
418431

419-
A weak reference to the interpreter won't prevent it from finalizing, but can
420-
be safely accessed after the interpreter no longer supports strong references,
421-
and even after the interpreter has been deleted. But, at that point, the weak
422-
reference can no longer be promoted to a strong reference.
432+
A weak reference to an interpreter won't prevent it from finalizing, and can
433+
be safely accessed after the interpreter no longer supports creating strong
434+
references, and even after the interpreter-state has been deleted. Deletion
435+
and duplication of the weak reference will always be allowed, but promotion
436+
(:c:func:`PyInterpreterWeakRef_AsStrong`) will always fail after the
437+
interpreter reaches a point where strong references have been waited on.
423438

424439
Strong Interpreter References
425440
*****************************
@@ -583,14 +598,25 @@ existing and new ``PyThreadState`` APIs. Namely:
583598
instead.
584599
585600
All of the ``PyGILState`` APIs are to be removed from the non-limited C API in
586-
Python 3.25. They will remain available in the stable ABI for compatibility.
601+
a future Python version. They will remain available in the stable ABI for
602+
compatibility.
603+
604+
It's worth noting that :c:func:`PyThreadState_Get` and
605+
:c:func:`PyThreadState_GetUnchecked` aren't perfect replacements for
606+
:c:func:`PyGILState_GetThisThreadState`, because
607+
:c:func:`PyGILState_GetThisThreadState` is able to return a thread state even
608+
when it is :term:`detached <attached thread state>`. This PEP intentionally
609+
doesn't leave a perfect replacement for this, because the GIL-state pointer
610+
(which holds the last used thread state by the thread) is only useful for
611+
those implementing :c:func:`PyThreadState_Ensure` or similar. It's not a
612+
common API to want as a user.
587613
588614
Backwards Compatibility
589615
=======================
590616
591617
This PEP specifies a breaking change with the removal of all the
592-
``PyGILState`` APIs from the public headers of the non-limited C API in 10
593-
years (Python 3.25).
618+
``PyGILState`` APIs from the public headers of the non-limited C API in a
619+
future version.
594620
595621
Security Implications
596622
=====================
@@ -676,24 +702,16 @@ held. Any future finalizer that wanted to acquire the lock would be deadlocked!
676702
/* Python interpreter has shut down */
677703
return NULL;
678704
}
679-
/* Temporarily hold a strong reference to ensure that the
680-
lock is released. */
681-
if (PyThreadState_Ensure(ref) < 0) {
682-
PyErr_NoMemory();
683-
PyInterpreterRef_Close(ref);
684-
return NULL;
685-
}
686705
687706
Py_BEGIN_ALLOW_THREADS;
688707
acquire_some_lock();
689-
Py_END_ALLOW_THREADS;
690708
691709
/* Do something while holding the lock.
692710
The interpreter won't finalize during this period. */
693711
// ...
694712
695713
release_some_lock();
696-
PyThreadState_Release();
714+
Py_END_ALLOW_THREADS;
697715
PyInterpreterRef_Close(ref);
698716
Py_RETURN_NONE;
699717
}
@@ -780,8 +798,9 @@ This is the same code, rewritten to use the new functions:
780798
Example: A Daemon Thread
781799
************************
782800
783-
Native daemon threads are still a use-case, and as such,
784-
they can still be used with this API:
801+
With this PEP, daemon threads are very similar to how native threads are used
802+
in the C API today. After calling :c:func:`PyThreadState_Ensure`, simply
803+
release the interpreter reference, allowing the interpreter to shut down.
785804
786805
.. code-block:: c
787806
@@ -1035,24 +1054,13 @@ functions related to interpreter initialization use it (simply because they
10351054
can't raise exceptions), and :c:func:`PyThreadState_Ensure` does not fall
10361055
under that category.
10371056
1038-
Open Issues
1039-
===========
1040-
1041-
.. _pep-788-deprecation:
1042-
1043-
When Should the GIL-state APIs be Removed?
1044-
------------------------------------------
1045-
1046-
:c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` have been around
1047-
for over two decades, and it's expected that the migration will be difficult.
1048-
Currently, the plan is to remove them in 10 years (opposed to the 5 years
1049-
required by :pep:`387`), but this is subject to further discussion, as it's
1050-
unclear if that's enough (or too much) time.
1057+
Acknowledgements
1058+
================
10511059
1052-
In addition, it's unclear whether to remove them at all. A
1053-
:term:`soft deprecation <soft deprecated>` could reasonably f 6AC0 it for these
1054-
functions if it's determined that a full ``PyGILState`` removal would
1055-
be too disruptive for the ecosystem.
1060+
This PEP is based on prior work, feedback, and discussions from many people,
1061+
including Victor Stinner, Antoine Pitrou, Da Woods, Sam Gross, Matt Page,
1062+
Ronald Oussoren, Matt Wozniski, Eric Snow, Steve Dower, Petr Viktorin,
1063+
and Gregory P. Smith.
10561064
10571065
Copyright
10581066
=========

0 commit comments

Comments
 (0)
0