@@ -578,31 +578,195 @@ Initializing and finalizing the interpreter
578578
579579.. _cautions-regarding-runtime-finalization :
580580
581- Cautions regarding runtime finalization
582- ---------------------------------------
581+ Cautions regarding interpreter finalization
582+ -------------------------------------------
583583
584584In the late stage of :term: `interpreter shutdown `, after attempting to wait for
585585non-daemon threads to exit (though this can be interrupted by
586586:class: `KeyboardInterrupt `) and running the :mod:`atexit` functions, the runtime
587- is marked as *finalizing*: :c:func:`Py_IsFinalizing` and
588- :func:`sys.is_finalizing` return true. At this point, only the *finalization
589- thread* that initiated finalization (typically the main thread) is allowed to
590- acquire the :term:`GIL`.
591-
592- If any thread, other than the finalization thread, attempts to attach a :term:`thread state`
593- during finalization, either explicitly or
594- implicitly, the thread enters **a permanently blocked state**
595- where it remains until the program exits. In most cases this is harmless, but this can result
596- in deadlock if a later stage of finalization attempts to acquire a lock owned by the
597- blocked thread, or otherwise waits on the blocked thread.
598-
599- Gross? Yes. This prevents random crashes and/or unexpectedly skipped C++
600- finalizations further up the call stack when such threads were forcibly exited
601- here in CPython 3.13 and earlier. The CPython runtime :term:`thread state` C APIs
602- have never had any error reporting or handling expectations at :term:`thread state`
603- attachment time that would've allowed for graceful exit from this situation. Changing that
604- would require new stable C APIs and rewriting the majority of C code in the
605- CPython ecosystem to use those with error handling.
587+ is marked as finalizing, meaning that :c:func:`Py_IsFinalizing` and
588+ :func:`sys.is_finalizing` return true. At this point, only the finalization
589+ thread (the thread that initiated finalization; this is typically the main thread)
590+ is allowed to :term:`attach <attached thread state>` a thread state.
591+
592+ Other threads that attempt to attach during finalization, either explicitly
593+ (such as via :c:func: `PyThreadState_Ensure ` or :c:macro: `Py_END_ALLOW_THREADS `)
594+ or implicitly (such as in-between bytecode instructions), will enter a
595+ **permanently blocked state**. Generally, this is harmless, but this can
596+ result in deadlocks. For example, a thread may be permanently blocked while
597+ holding a lock, meaning that the finalization thread can never acquire that
598+ lock.
599+
600+ Prior to CPython 3.13, the thread would exit instead of hanging,
601+ which led to other issues (see the warning note at
602+ :c:func: `PyThread_exit_thread `).
603+
604+ Gross? Yes. Starting in Python 3.15, there are a number of C APIs that make
605+ it possible to avoid these issues by temporarily preventing finalization:
606+
607+ .. seealso::
608+
609+ :pep:`788`
610+
611+ .. c:type:: PyInterpreterGuard
612+
613+ An opaque interpreter guard structure.
614+
615+ By holding an interpreter guard, the caller can ensure that the interpreter
616+ will not finalize until the guard is closed (through
617+ :c:func: `PyInterpreterGuard_Close `).
618+
619+ When a guard is held, a thread attempting to finalize the interpreter will
620+ have to wait until the guard is closed before threads can be blocked.
621+ After finalization has started, threads are forever unable to acquire
622+ guards for that interpreter. This means that if you forget to close an
623+ interpreter guard, the process will **permanently hang** during
624+ finalization!
625+
626+ .. versionadded:: next
627+
628+
629+ .. c:function:: PyInterpreterGuard *PyInterpreterGuard_FromCurrent(void)
630+
631+ Create a finalization guard for the current interpreter. This will prevent
632+ finalization from occuring until the guard is closed.
633+
634+ For example:
635+
636+ .. code-block:: c
637+
638+ // Temporarily prevent finalization.
639+ PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
640+ if (guard == NULL ) {
641+ // Finalization has already started or we're out of memory.
642+ return NULL;
643+ }
644+
645+ Py_BEGIN_ALLOW_THREADS;
646+ // Do some critical processing here. For example, we can safely acquire
647+ // locks that might be acquired by the finalization thread.
648+ Py_END_ALLOW_THREADS;
649+
650+ // Now that we're done with our critical processing, the interpreter is
651+ // allowed to finalize again.
652+ PyInterpreterGuard_Close (guard);
653+
654+ On success, this function returns a guard for the current interpreter;
655+ on failure, it returns ``NULL `` with an exception set.
656+
657+ This function will fail only if the current interpreter has already started
658+ finalizing, or if the process is out of memory.
659+
660+ The guard pointer returned by this function must be eventually closed
661+ with :c:func: `PyInterpreterGuard_Close `; failing to do so will result in
662+ the Python process infinitely hanging.
663+
664+ The caller must hold an :term: `attached thread state `.
665+
666+ .. versionadded :: next
667+
668+
669+ .. c :function :: PyInterpreterGuard *PyInterpreterGuard_FromView (PyInterpreterView *view)
670+
671+ Create a finalization guard for an interpreter through a view.
672+
673+ On success, this function returns a guard to the interpreter
674+ represented by *view *. The view is still valid after calling this
675+ function. The guard must eventually be closed with
676+ :c:func: `PyInterpreterGuard_Close `.
677+
678+ If the interpreter no longer exists, is already finalizing, or out of memory,
679+ then this function returns ``NULL `` without setting an exception.
680+
681+ The caller does not need to hold an :term: `attached thread state `.
682+
683+ .. versionadded :: next
684+
685+
686+ .. c :function :: void PyInterpreterGuard_Close (PyInterpreterGuard *guard)
687+
688+ Close an interpreter guard, allowing the interpreter to start
689+ finalization if no other guards remain. If an interpreter guard
690+ is never closed, the interpreter will infinitely wait when trying
691+ to enter finalization!
692+
693+ After an interpreter guard is closed, it may not be used in
694+ :c:func: `PyThreadState_Ensure `. Doing so will result in undefined
695+ behavior.
696+
697+ Currently, this function will deallocate *guard *, but this may change in
698+ the future.
699+
700+ This function cannot fail, and the caller doesn't need to hold an
701+ :term: `attached thread state `.
702+
703+ .. versionadded :: next
704+
705+
706+ Interpreter views
707+ -----------------
708+
709+ In some cases, it may be necessary to access an interpreter that may have been
710+ deleted. This can be done using interpreter views.
711+
712+ .. c :type :: PyInterpreterView
713+
714+ An opaque view of an interpreter.
715+
716+ This is a thread-safe way to access an interpreter that may have be
717+ finalizing or already destroyed.
718+
719+ .. versionadded :: next
720+
721+
722+ .. c :function :: PyInterpreterView *PyInterpreterView_FromCurrent (void)
723+
724+ Create a view to the current interpreter.
725+
726+ This function is generally meant to be used alongside
727+ :c:func:`PyInterpreterGuard_FromView` or :c:func:`PyThreadState_EnsureFromView`.
728+
729+ On success, this function returns a view to the current interpreter; on
730+ failure, it returns ``NULL `` with an exception set.
731+
732+ The caller must hold an :term: `attached thread state `.
733+
734+ .. versionadded :: next
735+
736+
737+ .. c :function :: void PyInterpreterView_Close (PyInterpreterView *view)
738+
739+ Close an interpreter view.
740+
741+ If an interpreter view is never closed, the view's memory will never be
742+ freed, but there are no other consequences. (In contrast, forgetting to
743+ close a guard will infinitely hang the main thread during finalization.)
744+
745+ Currently, this function will deallocate *view*, but this may change in
746+ the future.
747+
748+ This function cannot fail, and the caller doesn't need to hold an
749+ :term:`attached thread state`.
750+
751+
752+ .. c:function:: PyInterpreterView *PyInterpreterView_FromMain()
753+
754+ Create a view for the main interpreter (the first and default
755+ interpreter in a Python process; see
756+ :c:func: `PyInterpreterState_Main `).
757+
758+ On success, this function returns a view to the main
759+ interpreter; on failure, it returns ``NULL `` without an exception set.
760+ Failure indicates that the process is out of memory or that the main
761+ interpreter has finalized (or never existed).
762+
763+ Generally speaking, using this function is strongly discouraged, because
764+ it typically compromises subinterpreter support for a program. It exists
765+ for exceptional cases where there is no other option (such as when a native
766+ threading library doesn't provide a ``void *arg `` parameter that could be
767+ used to store a ``PyInterpreterGuard `` or ``PyInterpreterView `` pointer).
768+
769+ The caller does not need to hold an :term:`attached thread state`.
606770
607771
608772Process-wide parameters
0 commit comments