Handling threads

Steve Holden sholden at holdenweb.com
Wed Aug 7 08:51:06 EDT 2002


"Blair Hall" <b.hall at irl.cri.nz> wrote in message
news:3D50AB88.3341FE2 at irl.cri.nz...
> I have a problem with a class that uses the Thread module and starts a
> background thread
> when an object is created to do some misc stuff.
>
> My class has a 'close' method that terminates the background thread.
>
By setting a flag somehow which the thread notices and terminates on?

> However, the class __del__(), which calls close(), does not seem to be a
> satisfactory
> way of shutting down the thread. Actually, it is not the fault of
> __del__(), it is
> the fact that you do not seem to be able to rely on __del__() being
> called
> when an object is not needed any more.
>
Correct. This is particularly the case when you have a cyclic data structure
(a points to b, b points to c, c points to a would be a simple example).

> In my case, I find that even quiting the PythonWin environement is not
> enough to properly
> end the running process. I need to do Ctrl-Alt-Delete and end the
> PythonWin task (Windows95).
>
> Is there not a 'better' way to make my class easy to use ( it is very
> easy to forget to call close()! )?
>
A little experimentation shows that the "atexit" module can help you here.
It allows you to register functions to be called when your program
terminates, and it appears to call the registered functions when teh main
thread terminates, even if others are active. Here's a very small example
using a bound method (which is enough like a function to be usable):

#!/usr/bin/python
#
# Threaded test of atexit - not an example of thread-safety
#
import threading, time, sys, atexit

class sleeper(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.running = 1

    def run(self):
        while self.running:
            time.sleep(1)
            if self.running:
                sys.stdout.write('z')
                sys.stdout.flush()
        print "Terminated!"

    def enough(self):
        print "Terminating ..."
        self.running = 0

s = sleeper()
atexit.register(s.enough) # bound method

s.start()
time.sleep(7)
print "...\nEnough!"
sys.exit(0)

Be aware that termination by signal may affect the process in ways which
cause different handling of the registered exit functions. I'm not
sufficiently knoweldgabe about the threading module to be able to say.
Sounds like this might be good enough, though.

regards
-----------------------------------------------------------------------
Steve Holden                                 http://www.holdenweb.com/
Python Web Programming                http://pydish.holdenweb.com/pwp/
-----------------------------------------------------------------------








More information about the Python-list mailing list