Skip to content

Commit bcc1c73

Browse files
committed
Remove 'daemon'-ness as a property of threads.
1 parent 1e6285f commit bcc1c73

File tree

1 file changed

+18
-94
lines changed

1 file changed

+18
-94
lines changed

peps/pep-0788.rst

Lines changed: 18 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ object are wrong! There isn't any synchronization between the two GILs, so both
343343
the thread (who thinks it's in the subinterpreter) and the main thread could try
344344
to increment the reference count at the same time, causing a data race!
345345

346-
Concurrent Interpreter Deallocation Issues
347-
------------------------------------------
346+
Concurrent Interpreter Deallocation is Frustrating
347+
--------------------------------------------------
348348

349349
The other way of creating a native thread that can invoke Python,
350350
:c:func:`PyThreadState_New` and :c:func:`PyThreadState_Swap`, is a lot better
@@ -368,13 +368,11 @@ scratch and "reimagining" how to create, acquire and attach
368368
Preventing Interpreter Shutdown with Reference Counting
369369
-------------------------------------------------------
370370

371-
This PEP takes an approach where interpreters are given a reference count by
372-
non-daemon threads that want to (or do) hold an :term:`attached thread state`.
371+
This PEP takes an approach where an interpreter is given a reference count
372+
that prevents it from shutting down.
373373

374-
So, from a thread's perspective, holding a "strong reference" to the
375-
interpreter will make it safe to call the C API without worrying about
376-
the thread being hung. A strong reference held by a thread state will
377-
be held as long as thread state is "alive", even if it's detached.
374+
So, holding a "strong reference" to the interpreter will make it safe to
375+
call the C API without worrying about the thread being hung.
378376

379377
This means that interfacing Python (for example, in a C++ library) will need
380378
a reference to the interpreter in order to safely call the object, which is
@@ -391,12 +389,6 @@ to a strong reference can fail if the interpreter has already finalized, or
391389
reached a point during finalization where it can't be guaranteed that the
392390
thread won't hang.
393391

394-
If there's additional work after destroying the thread state, the thread
395-
can continue running as normal. If that work needs to finish before the
396-
program exits, it's still up to the user on how to join the thread, for
397-
example by using an :mod:`atexit` handler can be used to join it.
398-
This PEP isn't trying to reinvent how to create or join threads!
399-
400392
Removing the GIL-state APIs
401393
---------------------------
402394

@@ -424,21 +416,14 @@ Specification
424416
Interpreter References to Prevent Shutdown
425417
------------------------------------------
426418

427-
An interpreter will keep a reference count that's managed by threads.
428-
When the interpreter starts finalizing, it will until its reference count
419+
An interpreter will keep a reference count that's managed by users of the
420+
C API. When the interpreter starts finalizing, it will until its reference count
429421
reaches zero before proceeding to a point where threads will be hung.
430422
Note that this *is not* the same as joining the thread; the interpreter will
431-
only wait until the reference count is zero, typically via releasing non-daemon
432-
thread states with :c:func:`PyThreadState_Release`. The interpreter must not hang
433-
threads until this reference count has reached zero. Threads can hold as many
434-
references as they want, but in most cases, a thread will have one reference
435-
at a time, typically through the :term:`attached thread state`. After the reference count
436-
has reached zero, threads can no longer prevent the interpreter from shutting
437-
down.
438-
439-
An attached thread state is made non-daemon by holding a strong reference
440-
to the interpreter. When a non-daemon thread state is destroyed, it releases
441-
the reference.
423+
only wait until the reference count is zero, and then proceed. The interpreter
424+
must not hang threads until this reference count has reached zero.
425+
After the reference count has reached zero, threads can no longer prevent the
426+
interpreter from shutting down.
442427

443428
A weak reference to the interpreter won't prevent it from finalizing, but can
444429
be safely accessed after the interpreter no longer supports strong references,
@@ -474,7 +459,7 @@ Strong Interpreter References
474459
On success, this function will return ``0`` and set *ref_ptr* to a strong
475460
reference, and on failure, this function will return ``-1``.
476461
(Failure typically indicates that *interp* has already finished
477-
waiting on non-daemon threads).
462+
waiting on its reference count.)
478463
479464
The caller does not need to hold an :term:`attached thread state`.
480465
@@ -530,8 +515,8 @@ Weak Interpreter References
530515
On success, this function returns ``0`` and sets *ref_ptr* to a strong
531516
reference to the interpreter denoted by *wref*.
532517
533-
If the interpreter no longer exists or has already finished waiting for
534-
non-daemon threads, then this function returns ``-1``.
518+
If the interpreter no longer exists or has already finished waiting
519+
for its reference count to reach zero, then this function returns ``-1``.
535520
536521
This function is not safe to call in a re-entrant signal handler.
537522
@@ -544,43 +529,6 @@ Weak Interpreter References
544529
This function cannot fail, and the caller doesn't need to hold an
545530
:term:`attached thread state`.
546531
547-
Daemon and Non-daemon Thread States
548-
-----------------------------------
549-
550-
A non-daemon thread state is a thread state that holds a strong reference to an
551-
interpreter. The reference is released when the thread state is deleted, either
552-
by :c:func:`PyThreadState_Release` or a different thread state deletion
553-
function (such as :c:func:`PyThreadState_Delete`).
554-
555-
For backwards compatibility, all thread states created by existing APIs,
556-
including :c:func:`PyGILState_Ensure`, will remain daemon by default.
557-
See :ref:`pep-788-hanging-compat`.
558-
559-
.. c:function:: int PyThreadState_SetDaemon(int is_daemon)
560-
561-
Set the :term:`attached thread state` as non-daemon or daemon.
562-
563-
The attached thread state must not be the main thread for the
564-
interpreter. All thread states created without
565-
:c:func:`PyThreadState_Ensure` are daemon by default.
566-
567-
If the thread state is non-daemon, then the current interpreter will wait
568-
for this thread to finish before shutting down by holding a strong
569-
reference to the interpreter (see :c:func:`PyInterpreterRef_Get`). See also
570-
:attr:`threading.Thread.daemon`.
571-
572-
Return zero on success, non-zero *without* an exception set on failure.
573-
This function can only fail when setting the thread state to non-daemon.
574-
575-
.. c:function:: int PyThreadState_GetDaemon(int is_daemon)
576-
577-
Returns non-zero if the :term:`attached thread state` is daemon,
578-
and zero otherwise. See also and :c:func:`PyThreadState_SetDaemon`
579-
and :attr:`threading.Thread.daemon`.
580-
581-
This function cannot fail, other than with a fatal error if the caller
582-
has no :term:`attached thread state`.
583-
584532
Ensuring and Releasing Thread States
585533
------------------------------------
586534
@@ -604,10 +552,6 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
604552
if the interpreter matches *ref*, it is attached, and otherwise a new
605553
thread state is created.
606554
607-
The thread state attached by this function will be reused by
608-
subsequent calls to :c:func:`PyGILState_Ensure` in this thread, but
609-
:c:func:`PyGILState_Ensure` will *not* make the thread daemon again.
610-
611555
Return zero on success, and non-zero with the old attached thread state
612556
restored (which may have been ``NULL``).
613557
@@ -620,26 +564,7 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
620564
returning. The cached thread state as used by :c:func:`PyThreadState_Ensure`
621565
and :c:func:`PyGILState_Ensure` will also be restored.
622566
623-
This function cannot fail, but may hang the thread if the
624-
restored :term:`attached thread state` was daemon and the interpreter
625-
was finalized.
626-
627-
``threading`` Shutdown and Behavior
628-
-----------------------------------
629-
630-
An interpreter currently special-cases non-daemon threads created by
631-
:mod:`threading` and joins them before the interpreter does any other
632-
finalization.
633-
634-
:mod:`threading` will be changed to use :c:func:`PyThreadState_Ensure`, and
635-
will rely on the interpreter's strong reference to run until completion.
636-
:mod:`threading`-created threads will still be joined to release resources after
637-
this has happened.
638-
639-
Additionally, setting :attr:`threading.Thread.daemon` should
640-
correspond to calling :c:func:`PyThreadState_SetDaemon` in C. Otherwise,
641-
:c:func:`PyThreadState_GetDaemon` will have incorrect results in Python
642-
threads.
567+
This function cannot fail.
643568
644569
Deprecation of GIL-state APIs
645570
-----------------------------
@@ -744,7 +669,7 @@ held. Any future finalizer that wanted to acquire the lock would be deadlocked!
744669
{
745670
assert(PyThreadState_GetUnchecked() != NULL);
746671
PyInterpreterRef ref = PyInterpreterRef_Get();
747-
/* Temporarily make this thread non-daemon to ensure that the
672+
/* Temporarily hold a strong reference to ensure that the
748673
lock is released. */
749674
if (PyThreadState_Ensure(ref) < 0) {
750675
PyErr_NoMemory();
@@ -857,12 +782,11 @@ they can still be used with this API:
857782
PyInterpreterRef_Close(ref);
858783
return -1;
859784
}
860-
(void)PyThreadState_SetDaemon(1);
785+
PyInterpreterRef_Close(ref);
861786
if (PyRun_SimpleString("print(42)") < 0) {
862787
PyErr_Print();
863788
}
864789
PyThreadState_Release();
865-
PyInterpreterRef_Close(ref);
866790
return 0;
867791
}
868792

0 commit comments

Comments
 (0)