[Python-ideas] Threading hooks and disable gc per thread
Christian Heimes
lists at cheimes.de
Mon May 23 15:40:39 CEST 2011
Am 15.05.2011 13:13, schrieb Nick Coghlan:
(Sorry for the delay, I was swamped with work again)
> So the plan is to have threading.Thread support the hooks, while
> _thread.start_new_thread and creation of thread states at the C level
> (including via PyGILState_Ensure) will bypass them?
>
> That actually sounds reasonable to me (+0), but the PEP should at
> least discuss the rationale for the choice of level for the new
> feature. I also suggest storing the associated hook lists at the
> threading.Thread class object level rather than at the threading
> module level (supporting such modularity of state being a major
> advantage of only providing this feature at the higher level).
I've considered both places, too. _thread.start_new_thread() as well as
PyGILState_Ensure() would require a considerable amount of C coding for
a feature that won't affect performance in a noticeable way.
This is my answer against an C implementation in
_thread.start_new_thread(). It's far too much work for a feature that
can be implemented in Python easily. An implementation in the pure
Python threading module will work on PyPy, IronPython and Jython
instantly. I consider any library, that bypasses the threading module,
broken, too.
PyGILState_Ensure() or PyThreadState_New() are a different beast. I
concur, it would the best place for the hooks if I could think of a way
to implement the on-thread-stop hook. I don't see a way to execute some
code at the end of a thread without cooperation from the calling code.
> The PEP should also go into detail as to why having these hooks in a
> custom Thread subclass isn't sufficient (e.g. needing to support
> threads created by third party libraries, but note that such a
> rationale has a problem due to the _thread.start_new_thread loophole).
Understood.
> Composability through inheritance should also be discussed - the hook
> invocation should probably walk the MRO so it is easy to create Thread
> subclasses that include class specific hooks without inadvertently
> skipping the hooks installed on threading.Thread.
Good idea!
Do you think, it's sufficient to have hook methods like
class Thread:
_start_hooks = []
def on_thread_starting(self):
for hook, args, kwargs in self._start_hooks:
hook(*args, **kwargs)
? Subclasses of threading.Thread can easily overwrite the hook method
and call its parent's on_thread_starting().
> The possibility of passing exception information to thread_end hooks
> (ala __exit__ methods) should be considered, along with the general
> relationship between the threading hooks and the context management
> protocol.
That's an interesting idea! I'll consider it.
>> gc.disable_thread(), gc.enable_thread(), gc.isenabled_thread()
>> --------------------------------------------------------------
>
> The default setting for this should go in the interpreter state object
> rather than in a static variable (subinterpreters can then inherit the
> state of their parent interpreter when they are first created).
>
> Otherwise sounds reasonable. (+0)
A subinterpreter flag isn't enough. All subinterpreters share a common
GC list. A gc.collect() inside a subinterpreter run affects the entire
interpreter and not just the one subinterpreter. I've to think about the
issue of subinterpreters ...
If I understand the code correctly, gc.get_objects() punches a hole in
the subinterpreter isolation. It returns all tracked objects of the
current process -- from all subinterpreters. Is this a design issue? The
fact isn't mentioned in
http://docs.python.org/c-api/init.html#bugs-and-caveats.
Christian
More information about the Python-ideas
mailing list