On Feb 29, 4:34 pm, Preston Landers <[EMAIL PROTECTED]> wrote: > On Feb 29, 2:12 pm, [EMAIL PROTECTED] wrote: > > > If a thread adds an object it creates to a nonlocal > > collection, such as a class-static set, does it have to maintain a > > list of all such objects, just to get the right ones destroyed on > > completion? > > Yes. > > > Processes destroy their garbage hassle-free; how can > > threads? > > If you're asking "is there some automatic way to associate a external > resource with a thread so that it's deleted when the thread is done" > then the answer (to the best of my knowledge) is no. You would have > to take care of these details yourself once something outside your > thread got a reference to the resource. If you keep all references to > the resource inside the thread, then you can use the __del__ method of > the resource to take any cleanup actions. > > Also, processes don't always "destroy their garbage hassle free" if > you consider inter process communication. For instance, if you create > an object in one process then serialize it and pass it to another > process through e.g. an XMLRPC call, there's no automatic way for the > other process to be notified that the originating process exited. > You'd have to build that feature in. Exact same thing with threads. > > > And don't forget Thread.run( self ) in the example, if > > anyone ever wants to make use of the 'target' keyword. > > I don't understand what you're referring to.
In the initial counterexample, > class MyThread(Thread): > > def run(self): > while some_condition: > do_something() > do_something_after_the_thread_ends() , MyThread overrides 'run', so target is never called. It did create the picture to me though that: class MemHoldingThread( Thread ): def __init__( self, *a, **kwa ): Thread.__init__( self, *a, **kwa ) self.objs= set() self._args= ( self, )+ self._args def hold( self, obj ): self.objs.add( obj ) return obj def run( self ): Thread.run( self ) self._cleanup() def _cleanup( self ): for obj in self.objs: obj.clean() Then, def f( thd ): resrc= thd.hold( NewResource() ) infinite_loop( resrc ) MemHoldingThread( target= f ) thd is prepended to f's list of arguments so that it has a handle to its own thread object, but doesn't need an entire thread class-- middle ground. Then thd.hold adds any obj created to a thread-local set (and returns it). Then, _cleanup iterates over the set, and calls clean() on its items when f returns. At this point, I've gotten really really complicated. Not only have I still not shown the _at_exit call to MemHoldingThread static member _clean_all_remaining, but it's only useful if NewResource provides a list of globals/externals that it "adds itself to", or a clean() method to do them itself. But, you do get the benefit of not having to store each global/external in a Thread subclass object-- it does that for you-- as well as the benefit of being able to invoke the behavior without explicit additional subclasses. thing1= MemHoldingThread( target= thingf ); thing1.start() daemon1= MemHoldingThread( target= daemonf ); daemon1.start() server1= MemHoldingThread( target= serverf ); server1.start() rather than class Thing( Thread ):... thing1= Thing(); thing1.start() class Daemon( Thread ):... daemon1= Daemon(); daemon1.start() class Server( Thread ):... server1= Server(); server1.start() , which is useful sometimes, if even only a negligible proportion of them. <digressions> (Honestly, if Thread.start() returned self, class Thing( Thread ):... thing1= Thing().start() , or Thread( start= True ) launched it, that could go a long way, -- you just get keyword name collisions with target's parameters pretty soon.) What are the disadvantages to specifying an internal storage byte order for conversion to a string to use mmap with, by the way? And for all my seniors out there, you may be pleased to learn that I no longer think that all of my general little 5-liners should go in the standard library. </digressions> > you consider inter process communication. For instance, if you create > an object in one process then serialize it and pass it to another > process through e.g. an XMLRPC call, there's no automatic way for the > other process to be notified that the originating process exited. Maybe... but if all else fails you can pass the process ID in on connection creation, and periodically check if it's still alive. Do any Op. Sys.s have a OnProcTerminate( hproc, callback ) API? Sadly, stdin IPC is before my time. Windows actually even has ThreadSuspend and ThreadResume API; if suspending threads (and raising exceptions in them from others) threatens state consistency, what are their semantics? -- http://mail.python.org/mailman/listinfo/python-list