Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #61110
| Date | 2013-12-06 13:04 +1030 |
|---|---|
| From | Garthy <garthy_nhtyp@entropicsoftware.com> |
| Subject | Embedding multiple interpreters |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.3620.1386298086.18130.python-list@python.org> (permalink) |
Hi!
I hope I've got the right list here- there were a few to choose from. :}
I am trying to embed Python with multiple interpreters into an existing
application. I have things working fine with a single interpreter thus
far. I am running into problems when using multiple interpreters [1] and
I am presently trying to track down these issues. Can anyone familiar
with the process of embedding multiple interpreters have a skim of the
details below and let me know of any obvious problems? If I can get the
essentials right, then presumably it's just a matter of my tracking down
any problems with my code.
I am presently using Python 3.3.3.
What I am after:
- Each sub-interpreter will have its own dedicated thread. Each thread
will have no more than one sub-interpreter. Basically, there is a
one-to-one mapping between threads and interpreters (some threads are
unrelated to Python though).
- The default interpreter in the main thread will never be used,
although I can explicitly use it if it'll help in some way.
- Each thread is created and managed outside of Python. This can't be
readily changed.
- I have a single internal module I need to be able to use for each
interpreter.
- I load scripts into __main__ and create objects from it to bootstrap.
- I understand that for the most part only a single interpreter will be
running at a time due to the GIL. This is unfortunate but not a major
problem.
- I don't need to share objects between interpreters (if it is even
possible- I don't know).
- My fallback if I can't do this is to implement each instance in a
dedicated *process* rather than per-thread. However, there is a
significant cost to doing this that I would rather not incur.
Could I confirm:
- There is one GIL in a given process, shared amongst all (sub)
interpreters. There seems some disagreement on this one online, although
I'm fairly confident that there is only the one GIL.
- I am using the mod_wsgi source for inspiration. Is there a better
source for an example of embedding multiple interpreters?
A query re the doco:
http://docs.python.org/3/c-api/init.html#gilstate
"Python supports the creation of additional interpreters (using
Py_NewInterpreter()), but mixing multiple interpreters and the
PyGILState_*() API is unsupported."
Is this actually correct? mod_wsgi seems to do it. Have I misunderstood?
I've extracted what I have so far from my code into a form that can be
followed more easily. Hopefully I have not made any mistakes in doing
so. The essence of what my code calls should be as follows:
=== Global init, run once:
static PyThreadState *mtstate = NULL;
PyImport_AppendInittab("myinternalmodule", PyInit_myinternalmodule);
Py_SetProgramName((wchar_t *)"foo");
Pu_InitializeEx(0);
PyEval_InitThreads();
mtstate = PyThreadState_Get();
PyEval_ReleaseThread(mtstate);
=== Global shutdown, run once at end:
Py_Finalize();
=== Per-interpreter init in main thread before launching child thread:
(none thus far)
=== Init in dedicated thread for each interpreter:
// NB: Also protected by a single global non-Python mutex to be sure.
PyGILState_STATE gil = PyGILState_Ensure();
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
state = Py_NewInterpreter();
PyThreadState_Swap(save_tstate);
PyObject *mmodule = PyImport_AddModule("__main__");
Py_INCREF(mmodule);
PyImport_ImportModule("myinternalmodule");
PyGILState_Release(gil);
=== Shutdown in dedicated thread for each interpreter:
// NB: Also protected by the same single global non-Python mutex as in
the init.
PyGILState_STATE gil = PyGILState_Ensure();
PyThreadState *save_tstate = PyThreadState_Swap(state);
Py_EndInterpreter(state);
PyThreadState_Swap(save_tstate);
PyGILState_Release(gil);
=== Placed at top of scope where calls made to Python C API:
SafeLock lock;
=== SafeLock implementation:
class SafeLock
{
public:
SafeLock() {gil = PyGILState_Ensure();}
~SafeLock() {PyGILState_Release(gil);}
private:
PyGILState_STATE gil;
};
===
Does this look roughly right? Have I got the global and per-interpreter
init and shutdown right? Am I locking correctly in SafeLock- is
PyGILState_Ensure() and PyGILState_Release() sufficient?
Is there an authoritative summary of the global and per-interpreter init
and shutdown somewhere that I have missed? Any resource I should be reading?
Cheers,
Garth
[1] It presently crashes in Py_EndInterpreter() after running through a
series of tests during the shutdown of the 32nd interpreter I create. I
don't know if this is significant, but the tests pass for the first 31
interpreters.
Back to comp.lang.python | Previous | Next — Next in thread | Find similar | Unroll thread
Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-06 13:04 +1030
Re: Embedding multiple interpreters Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-12-06 19:58 +1300
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-06 18:29 +1030
Re: Embedding multiple interpreters Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-12-07 11:09 +1300
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-07 11:27 +1030
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-06 18:51 +1030
Re: Embedding multiple interpreters Chris Angelico <rosuav@gmail.com> - 2013-12-06 19:33 +1100
Re: Embedding multiple interpreters Chris Angelico <rosuav@gmail.com> - 2013-12-06 20:27 +1100
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-06 20:05 +1030
Re: Embedding multiple interpreters Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-12-07 11:23 +1300
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-07 11:01 +1030
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-06 20:14 +1030
Re: Embedding multiple interpreters Tim Golden <mail@timgolden.me.uk> - 2013-12-06 10:17 +0000
Re: Embedding multiple interpreters Chris Angelico <rosuav@gmail.com> - 2013-12-06 22:57 +1100
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-07 00:26 +1030
Re: Embedding multiple interpreters Garthy <garthy_nhtyp@entropicsoftware.com> - 2013-12-07 00:34 +1030
csiph-web