Killing threads

imageguy imageguy1206 at gmail.com
Sun Apr 5 09:05:57 EDT 2009


On Apr 4, 10:43 pm, ericwoodwo... at gmail.com wrote:
> Hi,
>      I'm new to python and even newer to threading and it seems as
> though I'm missing something fundamental about threads.  Basically I
> have a program that looks like this:
>
> class ThreadOne(threading.Thread):
>      while 1:
>           do stuff
>
> class ThreadTwo(threading.Thread):
>      while 1:
>           do other stuff
>
> first = ThreadOne()
> second = ThreadTwo()
>
> while 1:
>     do stuff
>
> The issue that I'm having is...I don't know how to kill this app in
> window.  I hit ctrl-c but that only seems to kill one of the threads.
> The rest of the app just lingers.  There's got to be a more graceful
> way but so far I haven't googled anything up.
>
> I'm using queues to talk between these threads so I could certainly
> put some kind of message on the queue that causes the threads to
> commit suicide but I'm thinking there's a more built in way to do what
> I want.  I'm just not sure what it is.
>
> I'd appreciate it if somebody could point me in the right direction.
> Thanks.

I am not an expert either, however, I think the standard practice is
to use and threading.Event to communicate with the threads.

So the structure goes something like this;
In the main thread set a threading.Event called 'keepgoing'.
Pass this object into the thread at instantiation or as a parameter in
the .start method
Over-ride the .run method to handle the process
Change the while loop's condition to check the .keepgoing.isSet()
In the primary thread, when you want the threads to stop, simply .clear
() the keepgoing event
The while loop terminates and at the end of the .run method, the
thread will terminate.

In the primary program, you should then .join() the worker threads.
- doing this will block the program until all of the thread have
stopped.

So your example would become;

class ThreadOne(threading.Thread):

   def __init__(self, keepgoing):
      threading.Thread.__init__(self)
      self.keepgoing = keepgoing

   def run(self)
     while self.keepgoing.isSet():
          do stuff thread one

class ThreadTwo(threading.Thread):

   def __init__(self, keepgoing):
      threading.Thread.__init__(self)
      self.keepgoing = keepgoing

   def run(self)
     while self.keepgoing.isSet():
          do stuff in thread two
#
#now start the main process
#

keepgoing = threading.Event()
keepgoing.set()

first = ThreadOne(keepgoing)
second = ThreadTwo(keepgoing)

# you could also pass in the variable with a thread.start() method,
which will then call the thread.run()

while 1:
   do stuff
   if stop_condition:    #keyboard interrupt ?
       keepgoing.clear()

for worker in threading.enumerate():
    if worker.isAlive():
        worker.join()

FULL DISCLAIMER:  I am NOT a threading expert and have limited
experience, so if this doesn't work, you are on your own !











More information about the Python-list mailing list