R08. When the interpreter stops - #189
Merged
Merged
Conversation
The last lesson about the runtime as a thing with a lifetime. R01 asked what has already happened before your first line. This one asks what is still to come after your last one. Every cell starts a child interpreter, because a notebook cannot watch its own shutdown. The cells cover the order of the end with sys.is_finalizing() next to each step, atexit coming back newest first and a callback registered during shutdown that never runs, what a late __del__ can still reach, an atexit callback and a finalizer that both raise while the exit status stays zero, the single generation two collection, and a subinterpreter nobody closed. The case worth the lesson is the daemon thread. Pass time.sleep and your finalizers run. Pass a function defined in your own module and its stack frame holds your module globals, the module dict is never cleared, and nothing in it is freed. Two Tier 1 recordings run nine endings on a release build and on a debug build, where that one thread leaves 12680 references alive against zero for the same objects held any other way. Six diagrams, three glossary terms, and a stale count fixed in R07, which said seven sample extensions where the table has eight.
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
R08 is the last lesson about the runtime as a thing with a lifetime. R01 asked what has already happened before your first line, and this one asks what is still to come after your last one.
Every cell starts a child interpreter, because a notebook cannot watch its own shutdown. The cells walk the order of the end with
sys.is_finalizing()printed next to each step, show atexit callbacks coming back newest first and one registered during shutdown that never runs at all, ask a late__del__what it can still reach, let an atexit callback and a finalizer both raise so you can read CPython's own ignored exception wording and watch the exit status stay at zero, catch the single generation two collection withgc.callbacks, and leave a subinterpreter open so its warning and its own atexit callback both turn up.The case that earns the lesson is the daemon thread. Pass
time.sleepand your finalizers run. Pass a function defined in your own module and its stack frame holds your module's globals, so the module dict is never cleared and nothing in it is freed. The two Tier 1 recordings run nine endings on a release build and on a debug build, and the debug one puts a number on it: 12680 references still alive at the end, against zero for the same five thousand objects held any other way.Twelve citations, all resolving against the pinned source. Six diagrams. Three new glossary terms in the startup and shutdown group: interpreter finalisation, atexit callback, and finalizing flag.
One drive-by fix in R07, which said four of seven sample extensions were refused where the table has eight rows.
Checked with
just check. Under Pyodide all nine code cells run and each one says it cannot start a process, which is the honest answer in a browser tab.