This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients eric.snow, jdemeyer, vstinner
Date 2019-04-25.15:03:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1556204605.72.0.0385912072707.issue36710@roundup.psfhosted.org>
In-reply-to
Content
> I don't really understand the rationale for these changes. What's wrong with the global variable _PyRuntime?
> What's the long-term goal for _PyRuntime? If you can't get rid of all occurrences of _PyRuntime, how does it help to get rid of *some* occurences?

The long term goal is to support multiple interpreter instances per process:

Eric Snow's PEP 554 "Multiple Interpreters in the Stdlib"
https://www.python.org/dev/peps/pep-0554/

Right now, there is a single instance of _PyRuntimeState: _PyRuntime. I would be interested to have one _PyRuntimeState per interpreter.

Maybe _PyRuntimeState should be reworked in the meanwhile. Right now, it's a strange beast: it contains things which are set before Python initialization and things which are set after. It contains C types and Python objects. Maybe some parts should be moved into PyInterpreterState or even PyThreadState. I don't know at this point. It takes time to look at each individual structure field...

Anyway, more generally, IMHO it's a bad practice to rely on a global variable. Python runtime should be "stateless".

The current implementation of CPython leaks dozens of *Python* objects at exit. For example, I started to work on this issue while working on https://bugzilla.redhat.com/show_bug.cgi?id=1696322 : Python doesn't clear 2 warnings variables at exit. When I looked into this issue, I also noticed that _PyRuntime.gc.garbage remains *alive* after Py_Finalize().

That's plain wrong: *all* Python objects must be cleared by Py_Finalize(). Two interpreters must *not* share any Python object.

Well, the PEP should better explain the rationale than me :-)

--

When I wrote PR 12934, I noticed that even getting the current thread state rely on _PyRuntime:

#define _PyThreadState_GET() \
    ((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))

That's wrong in the case of ceval.c: it should be possible to run _PyEval_EvalFrameDefault() twice at the same time in two threads using two "isolated" interpreters.

Well, PR 12934 doesn't fix all issues. It's just one small step towards "stateless" runtime and the even more long term of having one GIL per *interpeter*, rather than a single GIL per *process*.
History
Date User Action Args
2019-04-25 15:03:25vstinnersetrecipients: + vstinner, eric.snow, jdemeyer
2019-04-25 15:03:25vstinnersetmessageid: <1556204605.72.0.0385912072707.issue36710@roundup.psfhosted.org>
2019-04-25 15:03:25vstinnerlinkissue36710 messages
2019-04-25 15:03:25vstinnercreate